Tuesday 27 April 2004

DHTML JavaScript Tooltips

I use ToolTips a lot in my web apps, not just for 'help' information but also hovering over rows in a table to present additional information rather than having super-wide tables/lots of columns.

This DHTML JavaScript for Cross Browser Tooltips is the coolest implementation I've come across...

Thursday 22 April 2004

ASP.NET Browser Detection - uplevel FireFox?

I'm so impressed with the latest (0.8 last I checked) release of FireFox that I've started using it to test my ASP.NET apps.

Therefore I was pleasantly surprised to find someone(Rob)'s already figured out
Browser Testing and Detection Resources to encourage ASP.NET to play nicely with the latest IE-equivalent browsers...

Thanks to Mitch's blog on Web Controls and Browsercaps for pointing me there.

Wednesday 14 April 2004

C# and Excel Automation : Google Groups to the rescue

I don't post to newsgroups that often (although I try to contribute as much as I can to asp.net), but whenever I do I'm always amazed (and thankful) at the speed and quality of responses.

Overnight my problem with Excel automation was solved
Google Groups: Looping in Excel XP with C# -- Ranges and SpecialCells - reducing processing time from 90 minutes to 3 minutes!

Here is the 'working' code; loops through the Areas returned by the SpecialCells method so we only process non-empty cells...

Excel.Range range = sheet.UsedRange;

Excel.Range newrange = range.SpecialCells(Microsoft.Office.Interop.Excel.XlCellType.xlCellTypeConstants, (object)3 );
for (int areaid = 1; areaid <= newrange.Areas.Count; areaid++){
Excel.Range arearange = newrange.Areas.get_Item(areaid);
for (int row = 1; row <= arearange.Rows.Count; row++){
for (int col = 1; col <= arearange.Columns.Count; col++){
cell = (Excel.Range)arearange.Cells[row, col];
// do stuff with cell.Value2
}
}
}
FYI, the SpecialCells (object)3 parameter is the sum of relevant 'constants' below:
XlSpecialCellsValue 

xlErrors 16
xlLogical 4
xlNumbers 1
xlTextValues 2

Tuesday 6 April 2004

Automating Excel with C#

After much hair-pulling because I could not make Excel "work" as it should, I came across this article 328347 - PRB: "Member Not Found" Error Message When You Use a For Each Statement on an Excel Collection with Visual Basic .NET or Visual C# .NET

So that's why I couldn't loop through cells!

This seems to work better:
if (m_Excel.Workbooks.Count >= 1) {

Excel.Sheets sheets = book.Worksheets;
Excel.Range range,cell;
// foreach (Excel.Range cell in range.Cells ) BROKE http://support.microsoft.com/?kbid=328347
foreach (Excel.Worksheet sheet in sheets) {
range = sheet.UsedRange;
for (int row = 1; row <= range.Rows.Count; row++){
for (int col = 1; col <= range.Columns.Count; col++){
cell = (Excel.Range)range.Cells[row, col];
if (null != cell) {
if (null != cell.Value2) {
cellContent = cell.Value2.ToString();
// do something with the text...
}
}
}
}
}
}


Incidentally, I still don't know why ".Value2" ...

Monday 5 April 2004

File Extension filtering with .NET Regular Expressions

The 3 Leaf: .NET Regular Expression Repository provided a great starting point for writing a file extension filter to prevent certain file-types being uploaded in an ASP.NET HtmlInputFile control, using the RegularExpressionValidator.

Ultimately I came up with this
^([a-zA-Z]\:|\\)\\([^\\]+\\)*[^\/:*?<;>;|]+(\.txt|\.doc|\.xls|\.ppt|\.pdf|\.htm|\.html|\.zip)$
which seems to work OK, HOWEVER it's case-sensitive (so myFile.DoC won't upload).

If you want to only do validation on the server-side, a simple modification will enable 'case-insensitivity'
(?i)^([a-zA-Z]\:|\\)\\([^\\]+\\)*[^\/:*?<;>;|]+(\.txt|\.doc|\.xls|\.ppt|\.pdf|\.htm|\.html|\.zip)$

To really make it nice I wanted client-side validation as well, which meant building a custom validation control inheriting from BaseValidator. Most of the documentation I found was USELESS, but amazingly the 'beta' Longhorn documentation on Client-Side Functionality in a Server Control, Validator Control Samples and Client-Side Functionality in a Server Control
provided all the information I needed on the otherwise cryptic uses of RegisterValidatorCommonScript, RegisterValidatorDeclaration and the other bits and pieces required to implement a client- and server-side validator.

The result, InsensitiveRegularExpressionValidator is still in testing but will be posted soon.