Saturday, December 03, 2005

Quick SQL Reporting tip

I usually have to customize the data that's presented in a report in SQL Reporting services based on the currently logged in user. I'm guessing I'm not the only one.

The good news? It's really really easy!

What you can do is simply create a new String parameter (called something imaginative like 'CurrentUser' or something). When you create the parameter in the report designer, it'll give you a bunch of configuration options for the parameter. The main one you're interested in is the Default value.

Select 'Non-Queried' from the radio button list on the left, and then in the text-box that's enabled, enter the following function:
=Right(User!UserID, len(User!UserID)-instr(User!UserID, "\"))
Looks ugly, yeah? But it's quite logical, if you break it down a bit:
Right(string, length) gives you the right n characters of string. So if you entered Right("Monkey", 3) the resulting string would be 'key', the right 3 characters of the work 'Monkey'.

In this context, the string we're initial string is User!UserID. This is a report function that gets the login of the user viewing the report. The value is in the form DOMAIN/USER, which might be fine as is for your reporting. However, when I was using it, I just wanted the name part of the login, rather than both the domain and name. instr and len both combine to give me the user portion of the UserName. len(User!UserID) returns the length of the UserID string in its entirety. So for 'MARVIN\Ben' (my current login) it would return 10.
instr(String, StringToFind) returns the index of StringToFind within String. So taking my current login as an example, instr("MARVIN\Ben", "\") returns 7.
If you evaluate those 2 expressions, the outer expression then reads =Right(User!UserID, (10-3)), which is why the expression returns 'Ben' in my report.

That's not the clever bit, though.

The clever bit lies in the rest of the parameters.

If you have a datasource that requires parameters, say you're pulling results from a stored procedure, the report designer automatically adds those parameters to the parameters collection off the report. Since all the report parameters are evaluated in the order they appear in the list (Or are displayed in the order they are evaluated, if you like) you can out your CurrentUser parameter at the top of the list, and then if any of your query parameters need the current username, rather than repeat the function, you ca just refer to the CurrentUser parameter using Parameters!CurrentUser.Value. Just hide those parameters (more on that in a minute), set their defaults to the CurentUser parameter's value, and you're away!

The final stage is to hide the current user parameter. This differs depending on which version of SSRS you're using, but the 2 I know about are:

  1. the SSRS 2005 parameter dialog box has a 'Hide Parameter' check box. Just tick that and you're done
  2. In SSRS 2000 (which is what I'm using at home) if you clear the 'Prompt' value in the dialog, it'll automatically hide the parameter for you
But wait, there's more! Something that I was absolutely overjoyed to find out!

You set the default value of the CurrentUser parameter when the report fires up. Now normally, if the parameter is hidden, that value will never change. However if you un-hide that parameter, you can edit it and re-run the report using that value. This makes it an absolute doddle to debug and test. If you want to test the report output using several different users, you can just do it right there and then. And if you've set all the rest of the report parameters' defaults to refer to CurrentUser, then they'll all pick up the value you enter.

When you're done testing and are happy with the results that are being produced for your users, then you can just re-hide the parameter in the designer and publish the report. Once that's done, your report will produce custom output for each user, with no user intervention required or, in fact, allowed.

Clever eh? I love SQL Server Reporting Services. They're my friend.

Just wanted to share.

Wednesday, November 23, 2005

So much stuff, so little time...

Gah! So busy of late! Been writing lots of C#, and here are my cool features, in no particular order, and with no (at the time of writing) links (Sorry).

  • Refactoring Support
  • Windows Forms designer guide lines
  • Generics - say no more
  • Partial classes

There are so many more as well. I just love it. The joy is back.

Been working on some other cool stuff as well:
SQL Reporting Services - Just check it out. They rule!
SQL Server 2005 in general - Okay, I'm cheating. I'm on a SQL Server 2005 course this week.

Yes. I'm afraid there's nothing new to report. I'm just a jobbing developer, after all. Although I must admit, that amid the furore over the minor bugs that still inevitably remain in VS2005, Mike Gunderloy has some words of sanity.

Not a lot to share, but I have anyway. So there!

Wednesday, November 16, 2005

It's only a real little thing...

... But am I the only person who thinks that it would be a good idea fo a text editor to not only use punctuation and spacing to skip from word to word when you ctrl+crsr, but to include CapitalLetters in how it delimits word boundaries?

It's just been plaguing me over the past few days. I guess the alternative is to learn how to type properly...

Just asking the question...

Saturday, October 29, 2005

Great articles about Generics

Like most people, I daresay, the only way I've really been using generics over the past couple of months is for creating strongly types collections with System.Collections.Generics.List's, but I know in my heart of hearts that that's only half the story. Not even half of it. It's more like the first paragraph in the novel of Generics.

There are some great articles about generics and their use up on MSDN (Gratuitously nicked from the excellent

Generics FAQ: Fundamentals
Generics FAQ: .NET Framework
Generics FAQ: Best Practices
Generics FAQ: Tool Support

Not just sharing, I wanted to remember them as well...

Tuesday, October 25, 2005

A grand day out. And a Grand night in!

So I spent my Saturday in the company of a whole bunch of UK nerds this weekend. And oh my, what a cool day! I've never really been to any real developer events, certainly not one that was so fiercely community driven as DeveloperDeveloperDeveloper on Saturday. And oh my what a day it was.

In keeping with my general philosophy of trying to learn new stuff that I wouldn't really have an excuse to get to know about otherwise (i.e. pretty much avoiding anything that I'm likely to encounter in work) I saw some really great people enthusing about some really cool things.

My personal highlights included:

  • Barry Dorrans being very excited about MsBuild.
  • Liam Westley being very quick and cool about SubVersion (Despite the organisers' best efforts to kleep him off the agenda ;-))
  • Ben Lamb bubbling over with the funky new stuff headed up for C# 3.0

Those are just the ones that leap readiliy to mind. I also saw some cool stuff around the CLR in SQL Server 2005, new stuff in the System.XML namespace and many many more.

It was also just really cool to see so many people there, all of whom sort of share a bit of an interest. I've discovered through my travels in the world of the fledgling developer that it's something of a solitary path to tread. Thanls to all the organisers and attendees who made it such a fun day out. No doubt I'll be at the next one.

And then, to cap it all, got home from Reading only to find that Mrs Mawoo had organised a surprise birthday party for me, so there was much beer, merriment and general fun afterwards as well (although I'm ashamed to say I was the first to leave the party. Sat down for 5 minutes, and all of a sudden all of my friends had gone and Mrs Mawoo was waking me up to put my PJ's on. That's what you get for going out all day then trying to party after!)

And last but not least, a big thanks to John who let me scrounge a ride from my house to Reading. And back. Eventually!

That's it for now. No doubt there'll be more coming. I've got a bunch of tech stuff in my head just dying to come out, but so little time to actually write it! Damned commute! Gah!

Just wanted to share.

Sunday, October 02, 2005

Non Smokers look away now...

I know it's a particularly anti-social habit, as well as being about the least politically correct thing one can do, but I am a smoker.

Even worse, I don't even have the decency to be a victime of smoking. I dont't smoke 'Because I Can't Help It' or 'Because I need to' or any ligitimate reason like that.

I smoke because, bad as it is, and an unpopular an opinion as it is, I actually enjoy it. Every cigarette is as good as the last, and so on and so forth.

I smoke for the same reason some people eat chocolate. It's nice. It makes me feel good and I like it.

So I've just got one thing to say in this post. If you're a smoker, try a shisha pipe. I brought one back from my holiday in Egypt, and it's a really nice smoke. Bought back 4 flavours of tobacco, Cappucino, Pistachio, Apple and Cola (just to see what it was like). I'm working my way through my Cappucino at the minute, and it's really quite nice. Doesn't taste much like coffee, but it certainly has something about it that's coffee-esque.

Really quite nice. And smoing a shisha's very nice as well. I heartily recommend it.

Apologies for irrelevance, political incorrectness and bad-for-your-healthness.

Saturday, September 24, 2005

Debugging and testing serviced components

I've been working over the past couple of weeks on a new data access component at work. For many and varied reasons I decided to implement it as a serviced component. I wanted to take advantage of COM+'s ability to pool and maintain objects, as well as its tried and tested transaction management capabilities for slinging stuff in and out of a SQL Server database.

Since we're using VS 2005 to develop this new project, I wanted to take advantage of the integrated Unit Testing tools that come with it straight out of the box to make sure my component was working as expected. It was here that I encountered one or two things that I'm noting here so I can remember them:

You'll never get good code coverage stats
One of the things that needs to be configured when you enable Code Coverage in VS 2005 is exactly which DLL's it's going to create code coverage stats for.

Unfortnately there are 2 things that prevent VS from allowing it for DLL's that contain serviced components.

  • COM+ only looks in the GAC

If you want COM+ to recognise your component and run it as a server component (as opposed to a library component - more in that in a minute) you must install it in the GAC. This is no biggie. You just open up you WINDOWS/Assembly folder and drag/drop your DLL into it. Job done (thanks to the Fusion shell extension). You can also use GACUTIL.exe, but isn't dragging and dropping so much easier?

So you've got you component installed in the GAC, you then need to register it as a serviced component. Easy. Just use REGSVC.exe and bob's your uncle. One serviced component, configurable through the Component Services management utility. Cool.

The problem arises, however, when you try to set up code coverage to get stats on your component. You can only reference DLL files directly, and by default the 'Select Artifacts to Instrument' dialog only incldes those DLL's in your solution.

You can add other DLL's to the list, but try to navigate to the GAC and add them from there, and no dice. It somply won't allow you. This is either an intentional feature, or a side-effect of Fusion. Although in real life, the GAC is organised as a bunch of folders with subfolders and DLL files within them, when viewed in Explorer (as in, for instance, the Open File dialog) the assemblies appear as assembly objects. Since these aren't actual DLL files, the dialog won't allow you to add them.

Oh well. I'll have a play about and see if I can't work out a way around it. I've got a couple of ideas, but they all generally revolve around changing the way the component is referenced, and as such, change the overall context in which the abject will be used. Change the test environment too much from how it's actually going to be deployed, and you've negated your tests - they're no longer valid. Some (and I really do mean a very small amount) things can be changed for the purposes of testing and debugging, but not too much.

  • Serviced Components don't run in the normal application context

Actually, this isn't strictly true. Serviced components can be run inside the context of the calling application. And it's really simple to do, too. On the property sheet for the COM+ Application you've created, under the 'Activation' tab, select 'Library Application'. This will create the objects created by COM+ in the context of the calling application.

This can even be demonstrated really easily - just step through some code that calls a serviced component you've made in the debugger. If the application's running as a Server application (i.e. objects are actually created and run in dllhost.exe, rather than in the calling app) the debugger will just step over that code. Press F11 all you like, it won't do any good. Because the object isn't in the same process as the app being debugged, it won't step into it. However if you change the configuration to a Library application, you will be able to debug to your heart's content.

So what's that got to do with Code Coverage? Well, (I think) VS only produces results for code running in the TestHost process, or the ASP.NET equivalent, if you configure it that way. So, even if I did manage to add the GAC'ed DLL, my code coverage stats would be poor. UNLESS, for the purposes of testing I configured the app as a LIbrary Application.

I guess you'd only need to do it the once, though. Once you know your unit tests cover x% of your component's code, you can configure it how it'd be in production and leave it - if you're using Team System you'll be able to publish the results and keep a record of the coverage stats to take away. Nice!

Ignore the error messages
Okay. Don't ignore the error messages, just don't drill down to fixing the exact problem in the message. Because when you're working with Serviced components, you're working with (at least!) 2 sets of technology, the COM+ stuff and the .NET framework. As a result, the errors that get caught and passed between the 2 can lose a little in the translation. I had several errors crop up with null references and invalid security priviledges. They were invariably caused by either not installing the DLL in the GAC, or forgetting to register the component in the first place. Doh! Still, it took a bit of investigating, and I spent a while looking through the code trying to work out what was wrong. Guess I learnt a bit of a lesson - It's not always just about the code you've written.

Remember which actual file's being loaded
I spent a while building, rebuilding and generally buggering about with the code the first couple of times I made significant changes to how the component worked. Either I spotted a mistake and corrected it, or I got rid of a method, or I added a method and tried to call it. Some of the corrections got me all confused since I'd made various changes to the behaviour, but the results weren't changing.

Or, I'd add a method, write some code to call it, and then get a Mising Method exception.

What was going on? It's obvious now that I've spotted it, and it's even more obvious after what you've just read about Unit Testing, but the wierdness was being caused by the DLL not being re-installed in the GAC. I'd rebuild, and then when the test app called that assembly, it wasn't the fresh up-to-date assembly being called. It was the assembly that I'd already identitfied as being wrong that was running.


All in all, though, everything seems to be working nicely now, though. I just wanted to get some stuff to remember written down to help me remember it.

Jurt a quick plea for help, I wrote this pretty much off the top of my head. If anyone spots anything that's very incorrect, please drop a comment and let me know. Just to re-iterate, I certainly wouldn't take this post as gospel. They're just some things I wanted to make a note of, and generally thought I'd share.

Sunday, September 18, 2005

And... Breathe...

So I've been a bit busy over the past couple of weeks.

What have I been up to?

  1. Spent 2 weeks in Egypt
  2. Spent a week at work
  3. Went book shopping

Actually, that doesn't sound too busy at all. How come I feel like I haven't had 2 seeconds to sit and do anything? Oh well.

Doing some interesting stuff at the moment with System.EnterpriseServices and .NET remoting in C# 2.0. It's big fun, and if it all works, should make my life at work a bit easier. Nothing huge, but I'm currently replacing a web service with a remotable serviced component. The web service works fine, but because of the job it does, it needs to be as quick as possible. WebServices are great for a whole host of reasons, but for out purposes it could be better. It's a logging component for our intranet, which can be called across sites, but always to and from applications we've written.

There's no need for it to be interoparable over multiple environments (one of the biggest advantages of WebServices). As a result, one of the first advantages remoting has over WebServices is being able to send messages over TCP, and serialized using .NET's BinaryFormatter. This makes the messages going backwards and forwards much smaller. I haven't get any data on actual message size, but it took approximately 8 times as long to pull a dataset out through the webservice than it did to pull the same data out as business objects through a remoted component.

Add to that the nice things that COM+ brings to the table like JIT Activation, transaction management and object pooling and it should be a nice replacement.

And I get to play with C# and VS 2005.

What more could a boy want?

I'm sure I'll be writing more about my adventures in C# 2.0 shortly, but for now, I've got a couple of new books to read (this, this and this).

Just wanted to share.

Saturday, September 03, 2005

Very Very Quick...

...Before Mrs Mawoo finds me...

I'm currently blogging from a hotel lobby in Luxor, just about half way down the east coast of Egypt. I'll write more when I get back in a week or so, but here's a summary:

  • Egypt rocks.
  • Luxor rocks.
  • Aswan rocks
  • Pyramids rule.
  • Temples kick arse
  • The desert's ace
  • You can have too much of a train trip
  • Cairo doesn't rock.

I'll elaborate further when I've re-learnt how to type (funny how you can get out of practice with these things ;-)) But for now, I'm in Egypt. And that's cool.

Just wanted to share. I'm sure one day I'll get onto some .net stuff again one day...

Sunday, August 21, 2005

The perils of stubbing out methods

I only have a single-thread brain. Sad, but true. I can only really concentrate on one thing at a time.

For example, when I'm writing, I like to stub out sections of code so I can some back and flesh them out when I've finished something else. Take thei example of some code in process:

Public Function GetString(AllTheString as Boolean) as String
    If AllTheString Then
        Return "You asked for all the string"
        'Add the 'Not-All-The-String' in a minute.
        'Why not make a coffee?
    End If

You get the point. I can deal with the other path the code can take at some point in time. Perhaps after a coffee. However, this approach doesn't work in SQL Server 2000. I'm sure it's well documented and whatnot, but it really did give me some grief earlier today. Take this example:

    (@TestValue int)

IF EXISTS(SELECT TheKey FROM TheTable WHERE TheKey = @TestValue
    INSERT INTO AuditTable(Event, Time)
    VALUES ('This value was found: ' + @TestValue, GETDATE())
    /*I'll worry about this part in a minute
    I quite feel like a coffee roundabout now...*/

Hit the 'Validate SQL' button, and it'll return an error. A nice error? A helpful error? An error that might vaguely suggest that you might have a code path that doesn't actually so anything? No. What does it come back with?

Incorrect syntax near the keyword 'END'

Pointing at the last line of the script.

Took me ages of sifting through a long SPROC before I realised that was what it was trying to tell me. Bugger. All I was trying to dso was vlidate the SQL I had writen so I could move on to the other part.

Just wanted to share. Apologies for irrelevance and brevity, but it's late. All because of this very thing!

Saturday, August 13, 2005

Firsts, firsts and more firsts...

We're just starting a new project at work for the next few months. It's a fairly standard data mangling app, retreiving deatails about people, updating them stashing them back in a database. Nothing really out of the ordinary.

Well, it would seem that my team doesn't like to do the same thing over and over again (fair enough, neither do I!) so we're going to be doing a whole bunch of stuff that none of us have ever really done before. Our next project will be:

  • Written in C#
  • v2.0
  • in VS 05 beta
  • All developed on virtual PCs
  • Managed by Team System (Also running on a virtual server)

It's times like this that I really like not being chrged for by the hour. We had a meeting yesterday where we kind of figured that we can get the data-mangling parts written relatively quickly, so we could spend a bit more time doing nice twiddly bits for the UI. Nice. So there's going to be a few AJAX-easqe bits (I'm not even going to pretend that it's a new thing, but I'd never found a library quite as nice as Michael Schwarz' AJAX.NET for making it happen). IN real life, I;m sure we could knock something very dull rogether in a few weeks, but that would be it. It would be a very boring bit of kit. Just another in a long line of data mangling applications, And if I was being charged for by the hour, I'm sure that would suffice ('I don't care how boring it is, just do it as quick and cheap as possible!').

But I'm not. And that's cool. We get to learn new stuff (none of us have written in C# before) use new things (all betas, which is why we're doing it all on VPC's) and have some real fun (if you're into that sort of thing) with it.


Just wanted to share.

Saturday, August 06, 2005

Disaster at Benjimawoo Towers!

Of all the keys that had to stop working after my little bit of clumsiness a couple of weeks ago why did it have to be F11!

Yes, I know I can change the default key bindings, but i'm too lazy to change them from the VS defaults and reconfigure every time I rebuild.

Grr! Just wanted to share.

Friday, August 05, 2005

Short-circuiting comparisons

This was one of those things that I read about and though 'Huh. When am I ever going to use that?' Turns out it's pretty useful at times.

VB.NET can short circuit comparisons using the AndAlso an OrElse keywords.

What's short-circuiting?
Short circuiting occurs when you have multiple comparisons on a line and the outcome is known before you get to the end of the line. Take the following line of code:
If 1=2 And 3=3 Then
'Do some stuff
End If

You know after the first part (1=2) that the comparison is going to return false, but the second part is still evaluated (i.e. the machine still checks to see if 3 does in fact equal 3). However, if you were to use this:
If 1=2 AndAlso 3=3 Then
'Do some stuff
End If

The machine skips the 3=3 part of the comparison. Just ignores it. It knows that since 1!=2 the result is going to be false, so it just skips over the second part.

That contrived example doesn't look too useful. However, if we look at a real world example, all becomes clear:

Dim ds as Dataset = GetMyDataset()
Dim dr as DataRow = GetMyDataSet.Tables(0).Rows(0)
If Not IsDbNull(dr("FieldName")) And dr("FieldName") > 0 Then
'Do some stuff
End If

Because we're using the normal 'And', if the value in the row specified is null, the method will throw an exception because a value of type DBNull can't be cast to an integer. Although 'Not IsDbNull(dr("FieldName"))' returns false (because it is null) the second section is still evaluated. And because it's a null value, an exception is thrown.

However, if we use AndAlso, the comparison is short-circuited and it doesn't throw an exception:

Dim ds as Dataset = GetMyDataset()
Dim dr as DataRow = GetMyDataSet.Tables(0).Rows(0)
If Not IsDbNull(dr("FieldName")) AndAlso dr("FieldName") > 0 Then
'Do some stuff
End If

Because the first part of the comparison return false, the framework knows that the overall expression is going to return false, so it doesn't bother trying to evaluate the second part, and it doesn't throw an exception.

Needless to say, OrElse works in exactly the same way, but for Or's rather than And's.

It's come in handy for me a couple of times recently, anyway.

Just wanted to share.

Monday, August 01, 2005

Weeping update...

Although the title sounds like something you'd take to the doctor, I thought I'd offer something of an update to the last post I wrote about cleaning out my dad's computer.

As one kind commenter wrote, "it is far more productive to think of possible solutions"

Now I'm not proposing that I'm going to put a stop to all the various different flavours of intrusive marketing out there (blog comment spam, IM spam and the great granddaddy of them all, email spam), but I can at least make a note of what I did to try an alleviate the problem somewhat for my dad.

First, let me set the scene.

I have a teenage stepsister, and my teenage stepsister is a great one for IM, file sharing (although, as far as I know, it's all legal now) and generally caning the net for all its socially worth. She is also, at the end of the day, a teenager. Bit impetuous, bit naive, and a little too quick to believe popups that claim that her computer could be running quicker if she installed widget x.

I also have a father. He, like a lot of fathers, just wants his computer for invoicing, perhaps the odd bit of emailing, banking, and that's about it. He also once uttered the immortal line "Why couldn't they just leave it at Windows 3.01? Didn't it already do everything everyone wanted?". Hmmm. Although the gist of it was more about how computers have been getting more complicated than he wants.

So, to summarize:

1 teenage daughter who wants to use her computer to keep up with her mates, but isn't too aware that there are bad people out there who want to user her computer for slightly more nefarious deeds.

1 mature guy who needs his computer for work, but really doesn't want to have to deal with any more stuff to learn just to get his books done, which he's been doing in the same way since Office 97. Oh yes, and he hasn't really got time (who has, really, in the real world) to supervise her every online move.

I see a problem. How to secure his machine without adding the need for any more management. In fact, how to secure his machine network-wise without any apparent change in behaviour (of the machine, not him).

Well, the most thorough (and my preferred method) would be to start from scratch, stash all the documents and data away somewhere and spend a good few hours installing and configuring the machine to be nice and safe from (at least some of the nastier) nasties. Lock everything down, disable all the non-essential services, do some admin-type bits like shift his data onto a different partition from his system bits, stuff like that, and have everyone running on a non-admin account. However, although most of that would cause no noticeable change in the machine's behaviour, bits and pieces would require management, or to put it another way 'More bloody work'.

I would (and did), however, rightly or wrongly, hold short of installing a second firewall. My thinking is that with all the ports and services disabled that aren't needed, Windows firewall will be sufficient. It sits nicely in the background and slots in nicely with the rest of Windows Security Center. It doesn't have the learning overhead of a separate application.

I also whacked on MS Anti-Spyware for exactly the same reason. Although it's just a lightly re-branded version of Giant's Anti Spyware, it does at least integrate nicely with Windows and doesn't seem like too disparate of an app to learn. It's still quite consistent with (particularly the newer parts) the rest of Windows XP. I think I said before, it's perhaps not the swankiest, but it does at least do a reasonable job.

Those were the easy parts. Now came the hard part.

I started with turning the computer off.

I heard someone say once that the biggest security hole in any system lies between the keyboard and the chair. Any system (yes, ANY) can be compromised when you've got a real person pushing buttons at the business end.

So the most difficult part was getting my stepsister to take a bit of responsibility for what runs on her computer. I told her about checking for mysterious processes running in the background, what to do if she found one, how to check if something malicious was running and how to get rid of it. I told her about the perils of hitting 'yes' when asked "Do you want to enhance your browsing experience?". I went explained at great length (you ever tried to talk to a 13 year old girl about 'nerd stuff' for more than 10 minutes?) about how firewalls work, and what they do, and generally tried to make her a bit more aware of what's out there trying to get in.

The last part is the make-or-break factor. Everything before it is almost incidental. I can have an iron-clad OS, be running behind a rock solid firewall and have every scanner known to man running checking everything's OK. However, just like vampires, if I invite nasty things onto my machine, they (potentially) get a free rein over my computer. And that's the bit I really need to work on.

Oh to have longer than a short and hectic weekend to do it all in!

Just wanted to share.

Thursday, July 28, 2005

I am weeping as I write this

So I'm down in Plymouth for a few days. My sister's getting married tomorrow.

With a couple of hours to spare, I thought I'd borrow my dad's computer and check up on a couple of things (news, bank balance, that sort of thing).

I think I've discovered why people get so het up, annoyed and paranoid about their computers and the internet.

Dad's on AOL. Which I can almost forgive. No, I wouldn't go near them with a ten metre cattle prod, but each to their own. And it does automatically configure your web browser and mail client for you if you can stand their proprietary clients for each. Which I can't.) That's not too nasty a problem, I just hate AOL.

However, sadly I haven't got time at the moment to fix all the other stuff that's wrong with this machine. I'm writing this blog entry at what's left of the bottom of the IE browser window, because there's some sort of weird toolbar blocking the rest of the screen, that doesn't even appear in the toolbars menu soI've got no easy way of disabling it. So far I've hidden:

The Google toolbar
The MSN toolbar
The Yahoo toolbar
Some sort of explorer bar-esque toolbar that appears at the bottom of the browser. Goodness knows what that's for.

I'm writing in 3 word bursts, because every few seconds there's yet another popup telling me about today's greatest deals, or asking me whether or not I want to buy some game (it didn't stay open long enough for me to have a look at what it was, I can tell you!).

The only reason I can manage to get 3 words typed in a row at all is because I've turned the Messenger service off, killing the millions of net sends a second I was getting. I've disabled it for good measure, just in case...

It's running SP1 at the moment, and I'm guessing that the only reason it hasn't got SP2 installed is that the constant alerts that Windows Update flashes up saying that there are (still) new updates downloaded and ready to install on this computer are being left unheeded.

UPDATE: I have just this seond learnt that 'Bargains.exe' has been forced to close down due to an error. That was a little irrelevant aside, but it's really annoying when spyware interrupts your day crashing.

I don't use the phrase Syphilitic Whore of Intarweb Beelzebub lightly, and it truly does take some doing to get me to even think it. But this machine really is a Syphilitic Whore of Intarweb Beelzebub.

Looks like my job for the weekend's been decided...

  1. Uninstall obvious spyware crap (Honestly, who doesn't smell a rat when there's an entry in Add/Remove programs called 'Internet Optimizer' or 'Select Cashback'
  2. Install ALL updates, SP2, and everything since AND MS Anti-Spyware (Yes, I know it's not the greatest out there, but it's easy to use and better than nothing)
  3. Sort out Startup apps (I'm sure there are some if not nefarious, certainly dubious apps starting automatically)
  4. Wash, rinse, repeat

With a bit of luck, not only will dad's computer run a little swifter, but it'll make it a darned site easier for me to blog from his house!

That's enough for now. I'm gonna shutdown before I see yet another popup and have to throw ths computer out the window. And then I think I'll have a little lie down. And a stiff drink. There is much work to do...

But do you know what the realy depressing thing is? I doubt anyone'll notice. Popups and toolbars taking up two thirds of the screen seem to be de rigeur these days. People accept them in the same way they don't notice people pushing to the front of the queue or how they don't notice when shop staff don't say thank-you or smile (come on, it's not that hard!).

Just wanted to share.

Sunday, July 24, 2005

Two more reasons to own a camera phone...

Nice Melons!
Nice melons Mrs Mawoo!

Saturday, July 23, 2005

Cool marketing.

This site for GAP is right up there with Subservient Chicken for plain coolness.

Just wanted to share.

Thursday, July 21, 2005

Couple of things that I noticed today

2 quick things.

The first is something that's caught me out a couple of times, so I'm committing it to writing so I'll finally remember:

Using a DateTime field in the RowFilter of a Dataset
Since the RowFilter property is a string, it doesn't lend itself terribly well to filtering with DateTime values. Or at least the default DateTime.ToString format doesn't lend itself to being put in a RowFilter property. Picture the scene. You want to filter the DataView for your datagrid on today's date. You'd thing you could do it with:

theView.RowFilter = String.Format("DateField = #{0}#", DateTime.Today

But you'd be wrong. You might even think you'd be able to do it with the ToShortDateString method:

theView.RowFilter = String.Format("DateField = #{0}#", DateTime.Today.ToShortDateString()

And (and here's the rub) in some parts of the world, you'd be right. The ToShortDateString method is sensitive to the culture of the box it's running on. The RowFilter property, however, isn't. So, if you're in 'Merica, your ToShortDateString method produces this string for 23rd October 2004: "10/23/2005". If you're on t'other side of the pond (or anywhere else that formats its short dates properly) ToShortDateString produces: "23/10/2004".

Now because the RowFilter property isn't sensitive to the regional settings of the OS, it slings out the second string as an invalid date. The way to filter on dates, if you're in one of the enlightened countries that formats dates as they were meant to be formatted is thus:

theView.RowFilter = String.Format("DateField = #{0}#", DateTime.Today("MM/dd/yyyy")

The second thing is just something that I wrote today that made me feel good.

Possibly the most elegant peice of code I've ever seen
I like elegant code. I especially like it when elegant code is also (I think) efficient code. It's down the the DataView's RowFilter property again, and it uses my favourite String.Format function. It just looks truly beautiful, though:

theView.RowFilter = String.Format("Name in ('{0}')", String.Join(, "', '", StringArrayOfNames))

I just think it looks really neat. Of course, the String.Format method returns "Name in ('Tom', 'Dick', 'Harry')", but it's the simplicity and elegance of the String.Join function and putting the placeholder inthe format string ({0}) in quotes that just makes me think that everything's alright in the world.

You may have noticed I've had a good day. Just wanted to share some of the joy.

Wednesday, July 20, 2005

Couldn't resist...

This is just too cool!

Just wanted to share.

Monday, July 11, 2005

Day 1. Sweet. and Sour

So it was my first day at work today.

I have to say, the place I'm working is absolutely fantastic!

Get in, first thing I see is not 1 but 2 TFT monitors, both at 1280x1024. Aaaahhhhh! All your pixels are belong to us!

Follow that with a look through some actually well written and architected code, doing some really interesting things, and I was a happy happy boy!

The place is cool. I think I might just stay there.


The journey's almost exactly 2 1/2 hours each way. Mmm nice. Leave at 6.30, get home roundabout 8. Gah! Looks like I'm going to have to get myself some more books...

Just wanted to share the joy.

Saturday, July 09, 2005

Unbundle your products, dammit!

Bundled products are nice, especialy when you can get it cheaper buying the bundle.

However, I wish Logitech would unbundle their keyboards and mice.

I got one of the ealier Logitech cordless desktops a couple of years ago, and after a while the mouse packed up. No wories, I got a nice new MX100 laser mouse. Sweet!

However, it looks like my keyboard might be on its way out as well. Stupid thing - I spilt coffee on it yesterday, and having a look at it this morning, the printed circuity bit under the keys themselves is beginning to corrode. Should last a little longer, but I think I'll be looking at a new keyboard some time soonish.

What I really fancy is the nice Logitech MX 3100.


I already have the mouse, so I just want the MX3000 keyboard on its own. And can I get one? Can I buggery! I can ge the mouse on its own, not problem. But keyboard without the mouse? Hmmph!

Just wanted to rant. Grrr!

Friday, July 08, 2005

Visiting dignitary

Woah, wouldn't you know it? We've got a real life rock star coming to our little hamlet.

How cool's that?

UPDATE: Bugger. I'm gonna miss it. Why did my brother-in-law-to-be have to choose next weekend for his stag night?!

Thursday, July 07, 2005

Quick bit of Woo-age!

I know many of you have been following my glittering career with interest, awaiting every new development from the rollercoaster ride of one man trying to get someone to give him cash for code.

The last exciting installment saw me feeling like a cheap, washed up lady of the night, flaunting myself with that air of desparation common to jobseekers and ladies 'of a certain age' in night clubs.

Well as with all these things, it's paid off. I've found gainful employment with another company.

I'm actually quite chuffed with that. I think all told it took me 3 weeks between being told the old company were going to have to let me go, and finding some other sucker company to give me money for writing code.

I'm really stoked with them too. The interview made me think 'Hey, this is somewhere I really want to work'. There's some interesting stuff on the horizon, they're already looking at and training up on SQL Server 2005, VS 2005, .NET 2.0 and all that good stuff, which is a real rarity in the UK (I've discovered...).

Anyway. Just wanted to share some of my joy.

Wednesday, June 29, 2005

Nothing new, but just to remind myself...

Just watched Scott Hanselman's "Ten Tools in Ten Minutes" GrokTalk, and oh my what gems there are out there.

Some I know about, some I've used (like Reflector and the TestDriven Add-in).

Others are new to me, and one particular I love!

SlickRun is, in a word, the most useful thing I've seen in ages. Okay, not a word, but you get the point.

It's wicked. Just filling it up with 'magic words' at the minute.

My biggest joy with it is in being able to open up Firefox with a bunch of tabs open already, so I can just type in pr0n, and open all the best ones just open up! It's amost a shame the R is so far away from the 0...

Just wated to share the joy...

Tuesday, June 28, 2005

A useful bit of code I wrote...

The other day I had something to do that left me thinking 'Hey, y'know I can really use that again!'

So I thought I'd share it.

What I had was a web page with a bunch of complex(ish) formatting and (rightly or wrongly) some maths tied up in the repeater that produced the table. My boss then said to me 'Hey, you know what would be really cool is if we could export that data into Excel.

Hmm. I thought. There are 3 things I can do here.

I could re-write all my data-access and manipulation bits so that the underlying dataset had the values I wanted, and then spin that out into a text-file or something.

I could just export the whole page into Excel and have that monkey about translating this nice table (and all the other form elements) into an ugly, ill thought out spreadsheet.

Or I could simply take my page output, take out just the table (with no drop-downs, viewstate, or anything I didn't need) and sling that into Excel, taking advantage of Excel's fairly good support for HTML tables.

This last option seemed best to me, since apart from not having to re-write code, I could maintain all the color-coding from the HTML table and keep this report looking quite nice.

So, how could I do that? I tried playing about with some code making every element on the page invisible, except for the repeater (well, actually it was a set of repeaters) that produced the table, but I found out something weird:

Excel tries to render the hidden viewstate element as an image, and flashes an ugly redex when it can't decipher it, before turning it into just a blank cell at the top of the page. Not nice. Livable, but not nice. So I figured I'd have to parse the page output right down manually to create an export-type mode (as opposed to a display mode) for the page. Once I'd solved that problem in the short-term, that was when I figured I could make this a bit more useful by creating a page that naturally supported moded output. So this is how I did it:

I started by creating a supporting class to represent my mode. I wanted to be able to specify the markers that were going to live in the HTML that would delimit the sections that would be rendered. To keep things neat, I decided I'd do that by putting them in comment tags.

So this was my 'Mode' class:

Public Class PageMode
    Dim FModeName As String
    Dim FMarker As String
    Dim FContentType As PageModeContentType
    Dim StartFormatString As String = "<!--{0}-->"
    Dim EndFormatString As String = "<!--/{0}-->"
#Region " Properties "
    Public Property ModeName() As String
            Return FModeName
        End Get
        Set(ByVal Value As String)
            FModeName = Value
        End Set
    End Property
    Public Property Marker() As String
            If FMarker = "" Then
                Return String.Format(StartFormatString, FModeName)
                Return String.Format(StartFormatString, FMarker)
            End If
        End Get
        Set(ByVal Value As String)
            FMarker = Value
        End Set
    End Property
    Public ReadOnly Property EndMarker() As String
            Return String.Format(EndFormatString, FMarker)
        End Get
    End Property
    Public Property ContentType() As PageModeContentType
            Return FContentType
        End Get
        Set(ByVal Value As PageModeContentType)
            FContentType = Value
        End Set
    End Property
#End Region
#Region " Constructors "
    Private Sub New()
    End Sub
    Public Sub New(ByVal ModeName As String, ByVal MarkerText As String, ByVal ContentType As PageModeContentType)
        FModeName = ModeName
        FMarker = MarkerText
        FContentType = ContentType
    End Sub
    Public Sub New(ByVal ModeName As String)
        MyClass.New(ModeName, ModeName, PageModeContentType.web)
    End Sub
    Public Sub New(ByVal ModeName As String, ByVal MarkerText As String)
        MyClass.New(ModeName, MarkerText, PageModeContentType.web)
    End Sub
    Public Sub New(ByVal ModeName As String, ByVal ContentType As PageModeContentType)
        MyClass.New(ModeName, ModeName, ContentType)
    End Sub
#End Region
End Class

As you can see, it's got an unusual type in there for ContentType. This was just an enumeration I added so I didn't have to worry about playing with strings and stuff - And I love the intellisense support for Enums!

The rest of it's pretty standard. I've got some properties in there that let you define your own marker text. If, for instance, you had 3 or 4 different ways in which you wanted to show your page, you can just give them different marker values. Easy.

So once I'd put together the Mode class, it was time to actually do something with it.

To make some use of this, all I did was create a new class that inherited from Page and overrode its Render method to parse the page output and only include the sections marked out. Here's the full code:

Public Class SectionablePage
    Inherits Page
    Dim FPageMode As PageMode
    Protected Overrides Sub render(ByVal writer As HtmlTextWriter)
        If FPageMode Is Nothing Then
            'If there aren't any modes created, then render as normal
            Select Case FPageMode.ContentType
                Case PageModeContentType.web
                    Response.ContentType = "text/html"
                Case PageModeContentType.excel
                    Response.ContentType = "application/"
                    Response.AddHeader("content-disposition", "attachment; filename=""" & FPageMode.ModeName & ".xls""")
                Case PageModeContentType.word
                    Response.ContentType = "application/"
                    Response.AddHeader("content-disposition", "attachment; filename=Page.doc")
            End Select
            Dim sw As New StringWriter
            Dim hw As New HtmlTextWriter(sw)
            Dim EntirePage As String = sw.ToString
            Dim Marker As String = FPageMode.Marker
            Dim EndMarker As String = FPageMode.EndMarker
            Dim CurrentPoint As Integer = 0
            Dim SectionStart As Integer
            Dim SectionEnd As Integer
            Dim Section(1) As Integer
            Dim AllSections As New ArrayList
            Do While EntirePage.IndexOf(Marker, CurrentPoint) > -1
                Section = Section.CreateInstance(GetType(Integer), 2)
                Section(0) = EntirePage.IndexOf(Marker, CurrentPoint)
                Section(1) = EntirePage.IndexOf(EndMarker, Section(0)) + EndMarker.Length
                If Section(1) = -1 Then
                    'Check that there is a matching end tag to go with the start tag
                    Throw New SectionablePageException("Section is missing an end tag")
                    Exit Sub
                End If
                CurrentPoint = Section(1)
            For Each arSection As Integer() In AllSections
                writer.Write(EntirePage.Substring(arSection(0), arSection(1) - arSection(0)))
        End If
    End Sub
    Public Property Mode() As PageMode
            Return FPageMode
        End Get
        Set(ByVal Value As PageMode)
            FPageMode = Value
        End Set
    End Property
End Class

As you can see, I have a PageMode property, which just Gets and Sets the FPageMode variable (I could have just declared it as a public field, but I didn't want to. No good reason, I just didn't want to.)

In the render method, I start by checking that the page has had a mode set, and if it doesn't, then the page just renders as usual. If the page does have a mode set, then it decides what to do with it.

Firstly, it decides what flavour of content it's going to say it is. This is where MS Office's HTML support really comes in handy. Again, there's that ContentType enumeration. If I had more time, patience, or any real need, I would have made a slightly smarter way of doing that. As it is, though, I just use Select Case to determine the ContentType header for the page response. If it's a file, I also want to change the add the Content-Disposition header, mainly so I can change the filename.

After it's decided what it's doing, the real magic begins.

It calls the render method so that it spins the page content out into a great big string.

It then steps through the great big string looking for pairs of start and end tags for the PageMode, putting these pairs of values into an ArrayList.

Once it's got to the end of the string (i.e. the end of the page), it takes the pairs of start and end tags and outputs just those sections, all wrapped in HTML tags.

It's far from perfect. I think one of these days I'll make the ContentType a bit smarter, and maybe handle the errors a bit nicer, but at the end of the day, it's all there.

In use, it looks something like this:

<%@ Page Language="vb" AutoEventWireup="false" Codebehind="WebForm1.aspx.vb" Inherits="WebSectionsTester.WebForm1"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
        <meta name="GENERATOR" content="Microsoft Visual Studio .NET 7.1">
        <meta name="CODE_LANGUAGE" content="Visual Basic .NET 7.1">
        <meta name="vs_defaultClientScript" content="JavaScript">
        <meta name="vs_targetSchema" content="">
        <form id="Form1" method="post" runat="server">
            Pick section:<br>
            <asp:LinkButton ID="AllContent" Runat="server" text="All Content" /><br>
            <asp:LinkButton ID="Para1" Runat="server" text="Para 1" /><br>
            <asp:LinkButton ID="Para12" Runat="server" text="Para 12" /><br>
            <h1>This is the Title</h1>
            <p>This is paragraph 1</p>
            <p>This is paragraph 2</p>

    Private Sub Page_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        'Put user code to initialize the page here
    End Sub
    Public Sub ProduceContent(ByVal sender As Object, ByVal e As EventArgs) Handles AllContent.Click, Para1.Click, Para12.Click
        Dim ModeString As String = CType(sender, LinkButton).ID
        Dim theMode As New PageMode("Download", ModeString, PageModeContentType.web)
        Me.Mode = theMode
    End Sub

As you can see, you can create overlapping parts, you can have sections that are split into several parts. I think it's quite good (even if i do say so myself).

Sure, it's not perfect. I think it might be lighter on the server to parse it using Regular Expressions, rather than String.IndexOf(), and one of these days I'm going to get rid of that ContentType Enum and the Select Case in Render. But that's another thing for another day.

Just wanted to share. I promised something vaguely .NET related, didn't I.

Sunday, June 26, 2005

This from the BBC website...

Looks like they answered their own question there, doesn't it?

Wednesday, June 22, 2005

Aimless rambling through blogs

Sometimes it's nice to ramble aimlessly through blogs. Find one you like, find an entertaining bit of commentary, follow the link. Start over.

It's kind of like a country walk for my head. A wander thourgh a crazy forest of other people's thoughts. But I guess everyone gets that.

So imagine my surprise when I stumbled upon this metaphorical fairy-circle-with-real-life-hermit-and-complete-henge in my blog wander.

Just had to share. I particularly like rule 19:"Do you minimize your Outlook Distractions?"

I like the Outlook envelope in my taskbar. I tried for a time managing email by setting aside a specific time for checking and dealing with email, using it to plan my work for the next couple of hours and suchlike. Didn't work, though. I think because email was so abused at my old office, I'd get an email, not read it for sometimes as long as a 30 whole minutes, and have someone run over to my desk to ask me why I hadn't done whatever they'd asked me about in the mail.

Maybe I was just managing the people wrong, rather than the email. Who knows. It's all in the past. Anyway, I thought it was a right cracking little nugget. Definitely one to share with colleagues.

Just wanted to share.

Saturday, June 18, 2005

Well here it is...

I'm spent. It's been a long a stressful week this week, what with trying to find gainful employment, keep doing my regular job and such.

However, here's my CV (or Resume for those readers who don't speak Latin. Or live in the UK). Even leveraged some weird things into it. HTML CV? Nah. That's far too boring! I know (I thought one evening aftera little too much ale) I'll do an XML CV. Then transform ti with a spot of XSL, and then just for the kicker, I'll throw in a bit o' fine CSS magic to make it look sensible.

It doesn't look too pretty at the moment. Improvements will, inevitably be coming.

Just wanted to share...

Oh yeah, and if anyone can let me know how I can get the indentation to look right on the school and employment history in Firefox, then please do. It's been driving me insane all week.

Update: The link has been changed, so it should work fine in IE now. Apologies for any inconvenience.

Thursday, June 16, 2005

Oh the whoriness of it...

So my employer let me know on Monday that I was being made redundant. I've got a few more weeks until I'm out of the door, but in the meantime I've been applying for lots of jobs.

And my word don't I feel cheap and dirty!

I've been scouring job sites and applying for everything under the sun that I think I can do. Now the thing about job sites is that all the agencies go through them. So, now my spam mailbox is loaded 24/7 with mail from a whole load of agencies. Loads of them. I've even got my mail folders organised by agency. I can tell you I've 'registered' (a rather spurious term, if ever I saw one) with some 24 different agencies.

That doesn't make me feel like a whore, though.

The thing that really makes me feel cheap and dirty, and makes me feel like I need a shower, is having to actually read every mail, and (even worse) reply to them. Normally spam is given short shrift in Benjimawoo towers. Almost no-one has my real email address, and the very few newsletters and things I subscribe to go to my spam account. Product registrations (an even more insidious route to getting spam) goes to a separate webmail account.

I digress, though. Answering unsolicited (or at best semi-solicited) mail really grates.

But hopefully it'll keep me in a job. Which will be nice. I've had a few calls from various companies, and I'm being put forward for a few positions, so hopefully, I'll have some more news shortly.

It's all good fun, though.

Tuesday, June 14, 2005

Finally discovered for the charlatan I am!

Well I knew the dream couldn't last forever, and I just discovered that the client I've been working for isn't going to be needing any further development on the applications I look after.

As a result, I've been made redundant.


So if anyone's looking for a VB.NET developer in the London UK area, drop me a comment. Hell, if you just want to jeer and boo, then drop me a comment. In the spirit of unfailing optimism I'll be posting a CV at some point. In the meantime I've got sites to scour and people to cajole into employing me.

Apologies for irrelevance, begginess, and miscellaneous other stuff. There will be some technical bits coming soon. Promise.

Saturday, June 04, 2005

Oh so NOW I get it...

I've always been a bit mystified by the whole keyboard mappings thing. I know people really do get quite het up about keyboard mappings, and I know VS has a quite frankly bewildering keyboard mapping configuration properties thing.

I never really used it before, though.

However, I have just recently been feeling a little cheated because no software at all seems to support my very flash mouse. What I really wanted to be able to do was do some nice document navigation through my mouse. The buttons are nicely customisable, I can even assign key combinations to them (as opposed to standard operations or single keys). I was a bit miffed, though, because I can't assign keystroke chords to them (as used a lot in VS). However, through the gift of the keyboard mappings setup, I've got now got multiple keyboard combinations set up for my bookmark stuff (e.g. Next Bookmark is Ctrl+K, Ctrl+N as well as Ctrl+;). Once those are set up, I can assign the Ctrl+; combination to the 'next' button on my mouse (which I never really use anyway) and skip merrily through my code just using my mouse.

Pretty neat. I know it's nothing new at all, but it is to me. I'm impressed.

It's what camera phones were invented for...

The one visual gag that never EVER EVER dies!!!

Nice jugs Mrs Mawoo!!

Just wanted to share.

Thursday, May 19, 2005


Oh yes.

And I'm eternally indebted to the fine folks at Virgin for upgrading my broadband connection from 512Kbps to 1Mbps. Good work fella!


I've been very quiet of late. I know this.

I've been doing something even more fun than simply writing code. Writing code for money!

Yes. I've been in my job for a couple of months, now, and it's really good fun. Okay, sometimes it's not, but then most of the time it is.

I sadi a while ago that it was really useful having a second person in the background telling you where your application sucks, or at the very ;east not where it sucks, but what would make it even cooler.

Well now I have a whole squad of them. The upshot of it is that although I'm not reading so much, I am teaching myself lots of quite cool things. There are a couple of reasons why I haven't been frantically blogging about them:

  1. It's nothing particularly new
  2. It's not neccessarily .NET focused (I've been doing a bit of JavaScript, bit of network type stuff and so on...)
  3. It's not that interesting (I mean, who really wants to know about freezing table headings a la Excel?

So I've been quiet. There are stil a whole bunch of things I'm planning on doing in th enot too distant future, though:
  1. Get a wireless Router
  2. Get a New suit
  3. Start writing my software Magnum Opus
  4. lPut together a code library to help me write stuff after my software Magnum Opus
  5. Get a proper host
  6. Register my very own domain name
  7. Some other crap, I'm sure.

But what I've noticed is that now I write code for a living, rather than wanting to do less for fun, I actually want to do more for fun.

So that's where I've been. I've got a whole host of not-quite-so-new ASP.NET stuff to write about, couple of false starts, and an entire code demo in the making, which'll be along shortly.

Anyway. Just wanted to share.

Friday, May 13, 2005

Yes yes yes

Yes quiet. Yes more soon. Yes yes yes.

I don't care, though. The Hoff is on telly tonight.

If I was going to turn, I'd turn for him.

Just wanted to share.

Thursday, April 21, 2005

A really handy tip...

I can't remember where I heard or read it, but I remembered a handy tip for when you're having trouble working with datasets.

I was having a mare with a dataset earlier on today, and I thought that something was up with my columns, but I remembered this single method call (luckily!) just before I embarked on a woeful quest of 'for each c as DataColumn in MyDataSet.Tables(0)' and stuff like that.

Here it is:
Very handy.

Still didn't sort out the prblem, though. The dataset was exactly as I expected. It was just one of the assemblies I was working with that was playing up. Still, we live and learn, do we not?

Monday, April 18, 2005

It's like they reached into my head...

... And put what they found in there on the web.

MSDN's Coding4Fun sitelet (Is that even a real word??) does rock! A whole bunch of great brains doing nothng productive? I'm right on down wit' dat!

Thursday, April 14, 2005

Summer must be coming...

... I've just swatted my first wasp.

Wednesday, April 13, 2005

There are some things in life that I don't need to see...

And one of them is at the end of Scott and Rory's 4th tech-ed video.

The hopeful look on Rory's face. The little half-smile. That'll be haunting me for weeks...

Tuesday, April 12, 2005

Great little Add-in

I've been meaning to give the Copy Source as HTML a go fro ages. I reckon it would make my life much easier when it comes to code samples. And of course it would. Half the reason I don't put too many code samples on my blog is that I don't have the patience to read plain black text, nor do I have the patience to go through and manually highlight big blocks of code.

Lucky, then, that I now have this neat little VS add-in to let me put in things like this:

    Protected Function GetSubordinates(ByVal EID As Integer) As DataView

        GetSubordinates = New DataView(GetEmployees.Tables(0))

        GetSubordinates.RowFilter = "ReportsTo = " & EID

        Return GetSubordinates

    End Function

Useless bit of junk code, but hey neato! Just copied and pasted strainght in.


Apologies for only just getting on the bandwagon...

It's the little things...

Now and again I'll have a really productive day. Everything'll fall into place, compile first time and just run.

Sometimes, though, I just think of a really small thing and think to myself 'gee. Y'know, it really would be nicer if it did that.'

Like today. I'll expand on it later, when I've actually finishedit, but suffice to say it involves ASP.NET, Repeaters, home-grown viewstate persistence and a whole load of kludges that I never thought I'd have to go near.

Grrr. The devil is, indeed, very much in the detail!

Apologies for teasiness.

Cheap. Nasty. Dirty.

Just a quick one to tell both my readers that if they don't already, listen to Mondays.

Here is what it's not:

  • Safe for work
  • Intellectually Challenging
  • Mature
  • Educational

Here is what it is:
  • Funny
  • Crass. But in a good way.
  • Alternatively Educational

Well it's good clean fun, anyway. So listen to it. Both of you!

Do I get a Mondays mug now?

Wednesday, April 06, 2005

Blogging on Demand #6

I saw this in my referral whatsit just this evening, in fact, so in the interests of rapid response, here's a little bit about...

"accessing protected methods" vb (via Google)

Any methods in your class can (and usually will) be given a level of access, normally one of four:

There are a couple more as well which are used quite a bit, Shared and Virtual. I won't be going into them right now, since the reasoning behind them is a little different to the other four.
The different levels of access denote which code can 'see' the method, and call it. Briefly, the levels of access look like this:

Public methods (same with public variables) can be seen and called from any code that references it. If you add a reference to your project, and declare an instance of the class, you can call all the methods declared in that class as public.

Private methods and variables are declared within your class and can only be callled from within that class. If you create an instance of your class that has private methods within it, you will ot be able to call those methods. I often use private methods for quick functions that are needed all over the place within that class. They can, in fact, cover a multitude of evils (just between you and me). You'll notice that when you're working in VS, intellisense doesn't list private methods either. It's clever like that. As far as the code calling your class goes, private methods may as well not exist. I think you get the point.

Methods and variables declared as friend can be called only by code from within its assembly. This is quite handy if you've got some code that's used extensively throughout your application, but has some secret logic in it (for instance). OK, there are ways and means of finding it, through ILDASM and stuff, but for normal developers doing normal things, it's pretty much invisible. It's also something to look out for if you're writing an app that has multiple assemblies. As far as I know, the scope of friend methods is only the individual assembly, rather than the whole application.

Finally. Protected methods. What this whole post was meant to be about. Protected methods really come into play when you're talking about inheritance. And why? Because protected methods can only be called directly by an inherited class.

Take, for example, the Windows Forms Control class. All Windows Forms controls have a protected sub called OnPaint. As the name suggests, it paints the control. You may want to, however, do some custom action while the control is painting. Because the OnPaint method is declared as protected, you can't call it from the surrounding code. It can only be called from within itself. So how can you do something whizzy and flash with your control's OnPaint method? Well, you can inherit from it.

Create yourself a new class, that inherits from Control, and within that class you can change the way your control is painted. I did this recently with a dial control I was working on. In my case, I used OnPaint to specify where the hand on my dial was going and to draw it in, by declaring this method:

Private Overrides Sub OnPaint(sender as object, e as PaintEventargs)
' Call the original base class' OnPaint, so you don't have to draw the whole thing from scratch
'Do some drawing stuff here
End Sub

The important thing to note, however, is that the original MyBase.OnPaint method was available, because it was declared in the base class as Protected.

And that's how you access protected methods.

Tuesday, April 05, 2005

Want to put a Windows Control in your web app?

Mark's written this quick tutorial about how to do it.

Good work fella. I didn't even know this could be done until the other day - I think I might have to have a play about with this shortly...