Simon Green's Developer Blog
Developing .NET in the cold white north ...

Re-associate .aspx and .ascx files with the codebehind file

Saturday, 26 January 2008 12:26 by Simon

I recently inherited an application to work on which for whatever reason didn't have the code-behind files linked with the corresponding .aspx and .ascx files.

Visual studio looks for a codefile="class.cs" attribute in the page or control directive and this was missing.

So, when opening the application in Visual Studio the list of files was twice as long as it should have been and prevented Visual Studio from working some of it's magic like it does.

There were hundreds of files and editing each one to add the codefile="..." attribute to each page or control tag would have taken far too long.

What is the quickest way of turning this:

<%@ page language="c#" inherits="Company.Application.Class, Assembly" theme="Default" %>

... into this:

<%@ page language="c#" inherits="Company.Application.Class, Assembly" theme="Default" CodeBehind="Class.aspx.cs" %>

? Regular expressions of course !

Visual Studio can do search and replace and provides it own Regular Expression syntax that can be used (slightly different to most other versions strangely including the .NET framework itself but it works).

In case anyone needs to do this the syntax I used was:

Find what:
^{\<\%\@:bpage.+inherits=\"}{.+}\.{.+}\,{.+\"}{.+}$

Replace with:
\1\2.\3,\4 Codebehind="\3.aspx.cs"\5

Not forgetting to make sure that the 'Use:' option has 'Regular Expressions' selected.

Now, one click of the 'Replace All' button and the files were re-associated (after saving and re-opening the project).

For controls, I just replaced the 'page' part of the Find text with 'control'.

If you don't use a namespace then you may need to tweak the regex's a little but hopefully this should save you some work.

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Box Shot 3D - or 'do one thing and do it well !'

Sunday, 13 January 2008 10:33 by Simon

Photoshop is an amazing program. You can do anything with it ... if 'you' are a photoshop expert of course. I am not.

So, when I found myself wanting to spruce up a website and include some nice product box displays and screeshots that were more than just flat screen captures I trawled through the countless tutorials and 'how to' instructions on how to work magic with Photoshop to create such a masterpiece (because I am a software developer and not a graphic designer or marketing maestro). This is what I wanted:

But why is it such hard work? Isn't Photoshop supposed to make it easier to do things like this? Well yes ... if you are an expert with it (is this where I tell the programmers 'recursion joke?'*). The trouble with Photoshop is that it can do anything and everything and so is complex with a myriad of options and ways you need to discover to make it do what you want.

I can follow instructions and did get something almost looking how I wanted but it was far too difficult, took far too long and was far too hit and miss.

Of course, my brain waited until then to remind me that I had already bought a little shareware app called www.boxshot3d.com a few years earlier (for a handful of dollars) which did this one thing. First stop was the website where there was a new version waiting to download - nice to see it was still being developed and there was no upgrade fee to pay so I re-installed it and started to tinker with it. The interface had been updated and there were a few nice new features but it still focused on doing it's single task of rendering boxes and screenshots in 3D (now with the addition of rendering books too).

What a difference! Literally within minutes I was generating better results than I had following several Photoshop tutorials and better yet it was easy to reproduce things consistently.

Why is it better? Because it only tries to do a single thing but what it does it does incredibly well.

The two box-shots above were created with the app (shame prevents me from showing my attempts with Photoshop) and I also did a few screenshots for a website revamp similar to the one below.

Notice the nice Web 2.0 / Apple style 'reflection in the glossy desktop look'. It can also do a lot of things with light sources and shadows but I went for a simple look. If you need something similar it's worth checking out the http://www.boxshot3d.com/ website and getting a copy - it is well worth the money.

Also, a good reminder to keep apps simple and focused and able to "scratch an itch".

* In case you haven't heard it: "To understand recursion you first have to understand recursion."

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Tags:   , ,
Categories:  
Actions:   E-mail | del.icio.us | Permalink | Comments (0) | Comment RSSRSS comment feed

Stupid web trick - displaying an image without an image (Image2Html)

Saturday, 5 January 2008 13:00 by Simon

This is an old project I came across while seaching for a different project called Html2Image (which, given a URL would produce an image of the rendered page). I can only describe this as a 'stupid web trick' although there may be some uses for it. This one will take an image file and convert it to HTML.

Not to an HTML <img src="theimage.gif"/> tag though, to actual HTML - each pixel is an HTML element with the background color coming from a 'palette' of CSS styles. This is done to try and reduce the size of the generated XHTML and some RLE (Run Length Encoding) is also used to shrink repeated pixels of the same color to a single element entry in the output. For large images the output size will be prohibitive but for small images and icons it becomes more usable.

The net result is that you see the same image on the screen in the browser (or in an email client?) even if images are turned off. I did some experiments (again, several years ago) and it was possible to have richer-looking emails without needing images but again, things may have moved on and it may not be viable anymore.

The original project (at least 3 or 4 years years old) used <p> elements for each pixel but browsers must have moved on (and XHTML rendering is different to ye-olde-HTML) so I had to change the element tags to make it work again. It runs ok on IE and Safari but Mozilla / Firefox doesn't render it as it is (I honestly really don't know why people rave about it). I'm sure a bit of playing around with different element types and CSS attributes (line-height, font-size etc...) will produce something that runs. It may require different element types on different browsers (to cater for browsers that refuse to render empty elements and such like) but the approach will be the same.

Here are some screenshots of an example page which shows the same image displayed as a regular XHTML <img> tag and also as XHTML ...

Internet Explorer:

Safari:

Source Code: 

The VS.NET 2008 project is downloadable from the bottom of this post but here is the actual class that does the work and is usable in any version of the .NET runtime:

using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Net;
using System.Text;

namespace InteSoft.Web.Utility
{
    public static class Image2Html
    {
        private const string containerElement = "div";
        private const string containerClass = "image";
        private const string pixelElement = "img";
        private const string pixelClassPrefix = "p";

        public static string Convert(string url)
        {
            if (null == url)
                throw new ArgumentNullException("url");

            if (url.Length == 0)
                throw new ArgumentException("url required", "url");

            Uri uri = new Uri(url);
            return Convert(uri);
        }

        public static string Convert(Uri url)
        {
            if (null == url)
                throw new ArgumentNullException("url");

            if (!url.IsAbsoluteUri)
                throw new ArgumentException("absolute url required", "url");
           
            WebClient wc = new WebClient();
            byte[] imgBytes = wc.DownloadData(url);
            MemoryStream imgStream = new MemoryStream(imgBytes);
            Bitmap bitmap = (Bitmap)Image.FromStream(imgStream);

            return Convert(bitmap);
        }

        public static string Convert(Bitmap bitmap)
        {
            if (null == bitmap)
                throw new ArgumentNullException("bitmap");

            StringBuilder sb = new StringBuilder();
            sb.AppendFormat("<style>{0}.{1}{{line-height:1px;}}{0}.{1} {2}{{margin:0;padding:0;border:0;width:1px;height:1px;}}", containerElement, containerClass, pixelElement);
            ColorPalette colorPalette = bitmap.Palette;
            IDictionary<Color, int> paletteClassMap = new Dictionary<Color, int>(colorPalette.Entries.Length);
            for (int idx = 0; idx < colorPalette.Entries.Length; idx++)
            {
                Color color = colorPalette.Entries[idx];
                if (!paletteClassMap.ContainsKey(color))
                {
                    paletteClassMap.Add(color, idx);
                    sb.AppendFormat(".{0}{1:X2}{{background-color:#{2:X2}{3:X2}{4:X2};}}", pixelClassPrefix, idx, color.R, color.G, color.B);
                }
            }
            sb.AppendFormat("</style><{0} class=\"{1}\">", containerElement, containerClass);
            for (int y = 0; y < bitmap.Height; y++)
            {
                Color prevColor = bitmap.GetPixel(0, y);
                int count = 0;

                for(int x = 0; x < bitmap.Width; x++)
                {
                    Color color = bitmap.GetPixel(x, y);
                    count++;

                    if (color != prevColor || x == bitmap.Width - 1)
                    {
                        if (count == 1)
                        {
                            sb.AppendFormat("<{0} class=\"{1}{2:X2}\"/>", pixelElement, pixelClassPrefix, paletteClassMap[prevColor]);
                        }
                        else
                        {
                            sb.AppendFormat("<{0} class=\"{1}{2:X2}\" style=\"width:{3}px\"/>", pixelElement, pixelClassPrefix, paletteClassMap[prevColor], count);
                        }

                        prevColor = color;
                        count = 0;
                    }
                }
                sb.Append("<br/>");
            }

            sb.AppendFormat("</{0}>", containerElement);
           
            return sb.ToString();
        }
    }
}

Enjoy!

Download source: Image2Html.zip (8.23 kb)

Currently rated 2.0 by 4 people

  • Currently 2/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5
Tags:  
Categories:   .NET
Actions:   E-mail | del.icio.us | Permalink | Comments (0) | Comment RSSRSS comment feed