Rants Tagged with “.NET”
I've been scratching my head at the ASP.NET 2.0 TreeView control. This control is meant to show a tree of items and each item can have a link to it. For example, this is what I use for my menu on the left of the page.
It works great, except I had a specific case where I wanted to use it. I have a form for data entry where there is a hierarchy of items to select from. The user picks an item from the tree view and I read the Path of the TreeView control and store it as the selected item. This worked but everytime the user selected an item, I was getting a post-back to the server. It was as if AutoPostback had been enabled. But the TreeView control doesn’t have an AutoPostback property. I noticed that if I set the node’s NavigateUrl property that clicking on a node didn’t call __DoPostBack, but instead called the URL I specified in the NavigateUrl property. So I decided to make the NavigateUrl property “javascript:void(0)”. Essentially telling it that when the item is clicked, do nothing.
But it didn’t work. What was happening was that the control expected to navigate away from the current page, so selecting the item in the control did not matter. It simply ignored the “selection” process.
It was time to dig out Lutz Roeder’s Reflector to see what the TreeView was doing. I dove pretty deep into the actual rendering code of each node. I thought I was stuck or perhaps was going to having to cruft up some nasty hack using reflection to specify a NagivateUrl that would do the selection for me. That’s when I saw it. In the code, if you specify a Target for the node (or the entire TreeView) it will make the Selection code happen.
Why does it do this? It works this way because if the Target of the NavigateUrl is not the current page (e.g. Target=_blank or Target=SomeFrame), then the page isn’t going to change. Therefore, it needs to mark the current item as selected.
This left me a hacky way to my solution. I would specify the Target=”_self”, and NavigateUrl=”javascript:void(0)”. For example:
<asp:TreeView ID="TreeView1"
runat="server"
Target="_self">
<Nodes>
<asp:TreeNode Text="One"
NavigateUrl="javascript:void(0)" >
<asp:TreeNode Text="Two"
NavigateUrl="javascript:void(0)" />
</asp:TreeNode>
</Nodes>
<SelectedNodeStyle Font-Bold="True" />
</asp:TreeView>
Not an elegant solution, but a workable one.
Caveat:
I am one of the authors of the upcoming Microsoft MCST Training Kit (Exam 70-536) book from Microsoft Press. If you are planning to take the test, this book should help you get ready for it:
Part 2 of the my Avalon WPF DataBinding Article has gone live on MSDN. If you missed part 1, its here.
Thanks to Shawn Van Ness, he pointed me at this great utility that is helping me clean up some bad MSI's that are not letting me get WinFX installed correctly. Check it out.
My new Avalon WPF DataBinding Article has gone live on MSDN. Take a look. Part 2 will be published next week.
Since my announcement last year that there would not be an update to my book ("Pragmatic ADO.NET") to show the changes in ADO.NET 2.0, I have been asked what book I would recommend. I have scoured the ADO.NET 2.0 books and finally have a firm recommendation:
Pro ADO.NET 2.0, by Sahil Malik
While it is not the book I would have written, it is a very good book. It covers ADO.NET 2.0 very thoroughly and in a very readable manner. If you need an ADO.NET 2.0 book, go get this book today.
I read a lot of technical books. There are few to which I can say I enjoyed reading. Jeffrey Richter's new opus is one of them. Even at 600+ pages, it is an easy read with a ton of very important information. Chapters 23 & 24 alone are worth the price of the book (no one gets threading issues like Jeffrey Richter).
Go buy it...now...fast.
(Note: The link is not an amazon link with my amazon number. I get no fees or money if you buy his book.)
Every week (until I run out of Gems), I will post a new class or structure that I find in the .NET Framework that I never knew existed...and that I think rocks...
This week, the BitVector32 structure.
This little gem wraps a 32 bit integer to allow access to individual bits (instead of the BitArray or doing the binary math yourself, which is a bit cumbersome). It does this by allowing you to create bit masks (without having to understand the binary math) and to use the structure's indexer to get at that mask. For example:
int firstBit = BitVector32.CreateMask();
int secondBit = BitVector32.CreateMask(firstBit);
int thirdBit = BitVector32.CreateMask(secondBit);
BitVector vector = new BitVector(4);
bool isBit3 = vector[thirdBit];
or you can set it with the same syntax:
vector[secondBit] = true;
Nice, huh? Where it really shines is in packing bits. Bit packing is taking several smaller numbers and packing them into one large number. This is often done to decrease storage of especially small numbers.
If we wanted to store two numbers, instead of doing the binary math to figure out how many bits we needed to use and doing the bit shifting, the BitVector32 does it for us. Just create a section and specify the maximum number to store:
BitVector32.Section firstSection = BitVector32.CreateSection(25);
BitVector32.Section secondSection = BitVector32.CreateSection(100, firstSection);
Then you can just get and set the section with the indexer as well:
BitVector32 packedBits = new BitVector32(0);
packedBits[firstSection] = 10;
packedBits[secondSection] = 50;
Console.WriteLine(packedBits[firstSection]);
Console.WriteLine(packedBits[secondSection]);
Underneath it all is the 32 bit integer that you can always access to get the resulting number in your result:
Console.WriteLine(packedBits.Data);
One other nice feature is if you do ToString() on the structure, it shows you the number as binary to help debug bit issues you might have.
Console.WriteLine(packedBits);
// BitVector32{00000000000000011000000000001010}
Enjoy....
Interesting what can happen when you re-read the specification. I've been taking time in the "library" to read the 2.0 C# Specification. But instead of skiping the old stuff and concentrating on the new language stuff, I am reading the whole thing again. Something interesting I found in the 'switch' statement.
I am an old C++ hack from the COM days so I assumed that I knew how the switch worked:
int x = 1;
switch (x)
{
case 1:
Console.WriteLine("1");
break;
case 2:
Console.WriteLine("2");
break;
default:
Console.WriteLine("Unknown");
break;
}
Pretty basic stuff. But because of my C++ legacy, I assume that this wouldn't work (which it does):
switch (x)
{
default:
Console.WriteLine("Unknown");
break;
case 2:
Console.WriteLine("2");
break;
case 1:
Console.WriteLine("1");
break;
}
Ok, so order isn't that important (though I like the style of the default first). But because we don't have fall-through like in C++, I thought that linking multiple cases was kinda hacky...of course its because I didn't know about goto case:
switch (x)
{
case 1:
goto default;
case 2:
Console.WriteLine("2");
break;
case 3:
goto case 2;
default:
Console.WriteLine("Unknown");
break;
}
Look closely at two lines if you're not familiar with it. The 'goto default' indicates to go to the default case; while the 'goto case 2' says go to the code inside case 2! To further illustrate, this is what it would look like with a string switch:
string s = "3";
switch (s)
{
case "1":
goto default;
case "2":
Console.WriteLine("2");
break;
case "3":
goto case "2";
default:
Console.WriteLine("Unknown");
break;
}
Notice the 'goto case "2"' mimics the actual case label, so depending on what you're switching on, you'd change that for your case statement. Pretty sweet.
Just don't tell Microsoft I just learned this otherwise they might take my C# MVP away ;)
I was helping a friend out this evening trying to get a simple GridView working with a HyperLinkField from a database result and we ran into an interesting security feature that people might run into:
If you add a HyperLinkField to a GridView's Columns to allow a hyperlink in a column (pretty standard), it will create hyperlinks unless the URL starts with something other than http:// and https://. In our case, his DB has an URL of:
FILE://\\somemachine\someshare\somefile.txt
Because it was a full URL but didn't start with http or https, it didn't show the link. Change it to:
\\somemachine\someshare\somefile.txt
If you're interested, there was a Bug Report filed and MS explained why they did it:
http://lab.msdn.microsoft.com/productfeedback/viewfeedback.aspx?feedbackid=0400b837-db21-4828-90c7-4df607795501