logo
  • Jobs
  • About Me
  • Contact
  • Home

Archive for January, 2004

« Previous Entries

Online monkey mind

Gina Trapani’s scribbling.net (RSS) is one of my favorite blogs, technical or otherwise. Her latest post on her attempt to try and disconnect herself and gain more productive time in front of the “glowing box” is absolutely the best one Ive read by her.

She has such an eloquent way with words, and I just love how she draws you in with her stories. Now, if she would only display her RSS link more prominently. ;)

If you havent seen it yet, give her a read. You won’t regret it.

No Comments

Adventures In Babysitting

Recipe for Disaster

  • 1 Geo car
  • 1 foot snow
  • 1 2WD Nissan
  • 1 tow strap
  • 1 camcorder
  • 4 guys who’ve obviously never towed anything in their life

The result…

Warning: There is a lot of profanity, but if you dont want to hear it, turn your speakers down. It wont detract from the effect at all.

This is one of *the* funniest things I have ever seen…

[link via GeekGrrl]

3 Comments

How to install a component to the VS.NET toolbox

I think one of the things that makes a good component even better is that when I install it, it automatically installs itself to my Visual Studio.NET toolbox. For a while now, I’ve been looking at ways to accomplish this and finally came up with this.

* Download the component (with source and docs) — .zip.

I’ve created a base class that you can derive from that will do exactly this. You only have to implement three properties: ComponentName, ComponentPath, and TabName.

I’ve provided another property that will remove the tab when an uninstall occurs. Also, to make sure that the tab gets registered properly, I included a protected property that determines whether or not VS.NET is running. This is code that I found via Shawn Van Ness, who happened to be going through a similar problem.

Using this is very straightforward, and you should be able to hook it up to any installation utility that supports .NET assemblies as custom actions (InstallShield, VS.NET Setup, and WISE).

A simple implementation might look like this:

[
RunInstaller(true),
ToolboxItem(false)
]
public class MyComponentToolboxInstaller : MattBerther.Install.ToolboxInstallerBase
{
    protected override string ComponentName
    {
        get { return "My Control Package"; }
    }
 
    protected override string ComponentPath
    {
    	get
    	{
    	    return Path.Combine(
    	        this.Context.Parameters["INSTALLDIR"], "MyComponentLibrary.dll");
    	}
    }
 
    protected override string TabName
    {
    	get { return "My Company Name"; }
    }
 
    protected override bool UninstallRemovesTab
    {
        get { return true; }
    }
 
    public override Install(IDictionary stateSaver)
    {
	// Perform check to make sure that VS.NET isnt running
	// This will allow us to be certain that our tab shows up properly.
	while (this.IsVisualStudioRunning)
	{
		"One or more instances of Visual Studio .NET are running.\r\n\r\n" +
                                "To continue, please shutdown all " +
                                "running instances of VS.NET,\r\n and click 'Retry'.",
		"MattBerther.Com Controls", MessageBoxButtons.RetryCancel, MessageBoxIcon.Warning);
		if (dr == DialogResult.Cancel)
		{
			throw new InstallException("Unable to continue.");
		}
	}
 
	base.Install(stateSaver);
 
    }
}

I do hope that people find this useful, and can use it to provide a thorough installation process for their control libraries.

If you encounter any issues, please let me know.

1 Comment

The Butterfly Effect

Lindsay and I went to see this the other day and I gotta say I was quite impressed.

The movie starts out with a very interesting quote from Chaos Theory:

The flutter of a butterfly’s wings can cause a typhoon halfway around the world.

The movie is an interesting look into how people are a product of their environment, and how one small change in their environment (the flutter of the butterfly’s wings) can bring enormous change into their futures.

I was also quite surprised by Ashton Kutcher in this movie. I have been used to seeing him play the typical goofball character (ie: Dude, Wheres My Car? and Just Married). Seeing him play a serious role, and accomplishing it quite well was a welcome surprise.

If you like a movie that makes you think a little, make sure to check this one out.

No Comments

Bug/Feature Tracking Database

I have configured a bug tracking system for my pet projects. You can use this to see where I am at with any of the bugs/features for my current projects. I had some interesting requirements for the bug tracker that I wanted to use. Most importantly, it had to be free and support multiple projects.

Sean pointed me to Mantis at SourceForge.net which is an open-source PHP bug tracking implementation with a very rich feature set. If you are looking at a low cost way to get started with this, take a peek at it.

At this time, MovablePoster is the only application that Im tracking in there, but plan to move my other projects in there as time permits.

Please go ahead and continue to use the forums to report issues, and when a bug is determined to be a legitimate issue, I will move it over to Mantis and update the forums with a link to the issue, so that you can track its progress.

When you visit the site, you will be prompted for a login and password. You have two choices from here.

  1. You can login anonymously to browse the databse by clicking the ‘login anonymously’ link.
  2. If you wish to be notified of changes to the bug’s status, you will need to use a login. If you don’t have currently have one, go ahead and click ’signup for a new account’, and a new login will be created for you.
3 Comments

Implementing an ASP.NET Validator

For a project that I am working on, we are allowing users to enter a URI into ASP.NET TextBox controls. As I was implementing this, I thought that this would be a wonderful idea for a control.

I have written a thorough article that talks about the steps I went through to get this control ready for use, including supporting selected Uri schemes. Towards the end of the article, you will find a link to download this component for your own use if you so desire.

With ASP.NET, we were introduced to validators. In the most simplistic explanation, validators are used to verify that the information in a given control matches the values you are expecting.

All ASP.NET validators are derived from the abstract BaseValidator class, which provides a single abstract method (EvaluateIsValid) that we will need to implement.

ASP.NET includes several built-in controls, including:

  • RequiredFieldValidator — Makes the associated input control a required field.
  • CustomValidator — Performs user-defined validation on an input control.
  • RegularExpressionValidator — Validates whether the value of an associated input control matches the pattern specified by a regular expression.
  • CompareValidator — Compares the value entered by the user into an input control with the value entered into another input control or a constant value.
  • RangeValidator — Checks whether the value of an input control is within a specified range of values.

These validators are very well documented in the MSDN library, and I will not go into the details of these here.

For this article, we will walk through the process of creating a simple validator to verify that a value entered into a TextBox control is a valid Uri.

The process of accomplishing this is fairly basic. By deriving from the BaseValidator class, we inherit all of the functionality of the ASP.NET validators, and we simply need to provide our own implementation to determine whether or not the input is valid.

To do this, we will declare our class like this:

public class UriValidator : BaseValidator
{
    protected override bool EvaluateIsValid()
    {
        TextBox textbox = FindControl(this.ControlToValidate) as TextBox;
 
        if (textbox != null)
        {
            try
            {
                Uri uri = new Uri(textbox.Text);
                return true;
            }
            catch (UriFormatException)
            {
                return false;
            }
        }
 
        return false;
    }
}

What we are doing here is finding the TextBox control that we want to validate, and then attempt to assign the Text property to a new Uri instance. If the Text property is not a valid Uri, then this throws a UriFormatException, which in turn causes our validator to return false.

Next, the BaseValidator class offers a virtual method called ControlPropertiesValid, which will allow us to validate that the ControlToValidate matches a specific type. In our case, we only want to validate TextBox controls, so we will add the following method to our UriValidator class.

protected override bool ControlPropertiesValid()
{
    Control ctrl = FindControl(this.ControlToValidate) as TextBox;
    return ctrl != null;
}

At this point, we have a fully functional validator, which will support any type of Uri that is submitted. However, we may run across the case where we want to limit the scheme of the Uri. To accomplish this, let’s create a new enum, which will correspond to the available Uri schemes.

The code will look something like this:

[
Flags(),
Serializable()
]
public enum UriScheme
{
    File = 0x0001,
    Ftp = 0x0002,
    Gopher = 0x0004,
    Http = 0x0008,
    Https = 0x0010,
    Mailto = 0x0020,
    News = 0x0040,
    Nntp = 0x0080,
    All = UriScheme.File | UriScheme.Ftp |
        UriScheme.Gopher | UriScheme.Http | UriScheme.Https |
        UriScheme.Mailto | UriScheme.News | UriScheme.Nntp
}

Notice that we have marked our enum with the FlagsAttribute. This is necessary so that we can assign a bitwise mask of values. For example: UriScheme.Http | UriScheme.Https to only allow the Http and Https schemes to validate.

Now that we have our enum set up, we will want to create a property that we can access via code or designer to set the Uri schemes that we wish to accept.

Let’s add this property accessor to our UriValidator class:

[
Category("Behavior"),
Description("Gets or sets a value indicating which Uri schemes will be accepted."),
DefaultValue("All")
]
public string AcceptedSchemes
{
    get
    {
        object savedState = this.ViewState["AcceptedSchemes"];
        if (savedState != null)
        {
            return ((UriScheme)savedState).ToString();
        }
        return UriScheme.All.ToString();
    }
    set
    {
        this.ViewState["AcceptedSchemes"] = (UriScheme)Enum.Parse(
            typeof(UriScheme), value, false);
    }
}

We have specified this property as a string so that the user can enter these into the designer property grid as a comma-delimited list of values (ie: Http, Https, Mailto), which still allowing the users to use the enumeration in code (ie: AcceptedSchemes = UriScheme.Http | UriScheme.Https | UriScheme.Mailto).

We have also specified that this property live in viewstate so that the value will be persisted across postbacks.

Now that we have support for accepted schemes, we will need to modify the EvaluateIsValid method to also validate that a supported scheme is contained in the input value.

To do this, let’s slightly modify the method and add a helper method to assist us in validating the scheme.

protected override bool EvaluateIsValid()
{
    TextBox textbox = FindControl(
        this.ControlToValidate) as TextBox;
 
    if (textbox != null)
    {
        try
        {
            Uri uri = new Uri(textbox.Text);
            return IsValidScheme(uri.Scheme);
        }
        catch (UriFormatException)
        {
            return false;
        }
    }
 
    return false;
}
 
private bool IsValidScheme(string scheme)
{
    if (this.AcceptedSchemes.IndexOf("All") != -1)
    {
	    return true;
    }
 
    if (scheme ==  Uri.UriSchemeFile)
    {
  	  return this.AcceptedSchemes.IndexOf("File") != -1;
    }
    else if (scheme == Uri.UriSchemeFtp)
    {
	    return this.AcceptedSchemes.IndexOf("Ftp") != -1;
    }
    else if (scheme == Uri.UriSchemeGopher)
    {
	    return this.AcceptedSchemes.IndexOf("Gopher") != -1;
    }
    else if (scheme == Uri.UriSchemeHttp)
    {
	    return this.AcceptedSchemes.IndexOf("Http") != -1;
    }
    else if (scheme == Uri.UriSchemeHttps)
    {
	    return this.AcceptedSchemes.IndexOf("Https") != -1;
    }
    else if (scheme == Uri.UriSchemeMailto)
    {
	    return this.AcceptedSchemes.IndexOf("Mailto") != -1;
    }
    else if (scheme == Uri.UriSchemeNews)
    {
	    return this.AcceptedSchemes.IndexOf("News") != -1;
    }
    else if (scheme == Uri.UriSchemeNntp)
    {
	    return this.AcceptedSchemes.IndexOf("Nntp") != -1;
    }
    else
    {
	    return false;
    }
}

With this, we have completed our validator and are ready to drop this onto a webform to make sure everything works.

In it’s most simplest form, this control can be used like this:

<html>
    <body>
	<form runat="server" ID="Form1">
   	    <h3>UriValidator</h3>
 
	    <asp :TextBox id="textbox"
	        runat="server"></asp>
 
	    <hw :UriValidator id="urlValidator"
	        runat="server" AcceptedSchemes="Http, Https"
	        ControlToValidate="textbox"
	        ErrorMessage="The Uri entered is an incorrect format."/>
 
	    <asp :Button id="button" runat="server"
	        Text="Submit"></asp>
	</form>
    </body>
</html>

When you run this project, you can test that this is working by entering http://www.mattberther.com into the textbox. You will see that no validation errors are occurring. However, if you change the textbox value to Foo, you will notice that you get an error, because ‘Foo’ is not a valid Uri.

Now, one final test to validate that our scheme processing is working. Enter ftp://ftp.microsoft.com into the textbox, and click the button. Again, you will see that it fails, because our accepted schemes do not include ftp. Success!

This code has been documented using the /// documentation syntax. I prefer to use NDoc, which can be found at SourceForge, as my documentation generator.

In the download, you will find the prebuilt component, along with source and an NDoc generated .chm file that you can use for reference when using the component.

Your feedback is important to me and I am always willing to make improvements. If you found this article useful or have any other thoughts, please let me know.

Lastly, I have also submitted this article to CodeProject, so if you do find it useful, go ahead and jump over there and give me a vote.

No Comments

VS.NET and non-admin accounts

After using Visual Studio.NET and the MSDN library/built-in help for a few days, I noticed that every time I tried to use the help, a lot of the topics tried to run the Windows installer. The installer would fail, since I was not an admin on the account.

To resolve this, I had to temporarily grant the user administrative privileges and run the MSDN library to let the installer run. After running the library and selecting a topic to make the installer run, I was able to remove the administrative privileges and everything appears to run fine now.

Apparently, VS.NET just needed a little kick start.

No Comments

The Xml Files

I found out earlier today that Aaron Skonnard has a blog online, complete with RSS. In case you arent familiar with Aaron, he is the author of the MSDN Xml Files columns, and an all around Xml guru.

Subscribed.

No Comments

Rory on DotNetRocks

Make sure you don’t miss Rory on the latest DotNetRocks show… This is hysterical.

No Comments

Duplication Checker (Simian)

Earlier this week, I came across a really cool tool for checking and detecting duplicated code throughout a group of files.

Simian, although written in Java, works very well for C# code and it is lighting fast. Output can be directed to the console, or to a file (in either plain, XML or EMacs formats). Included in the package is a basic stylesheet so that you can view your XML in a more meaningful way.

Current supported languages include:

  • Java
  • C#
  • C++
  • Javascript (ECMAScript)
  • COBOL, ABAP
  • Ruby
  • JSP (partial)
  • HTML (partial)
  • XML (partial)
  • Visual Basic (partial)

Simian has a free license available for non-commercial and open source user. If you need it in another capacity, different licenses are available, including a personal license for $29. What a small price to pay for the benefits of time saved performing maintenance, debugging and refactoring.

1 Comment
« Previous Entries
flag
Favorite Charity
wounded warrior project
Search
Social
  • mattberther on twitter
  • mattberther on linkedin
Syndication
Archives
  • January 2010
  • September 2009
  • July 2009
  • June 2009
  • February 2009
  • January 2009
  • December 2008
  • November 2008
  • September 2008
  • August 2008
  • June 2008
  • May 2008
  • April 2008
  • March 2008
  • February 2008
  • January 2008
  • December 2007
  • November 2007
  • October 2007
  • September 2007
  • August 2007
  • July 2007
  • June 2007
  • May 2007
  • April 2007
  • March 2007
  • February 2007
  • January 2007
  • December 2006
  • November 2006
  • October 2006
  • September 2006
  • August 2006
  • July 2006
  • June 2006
  • May 2006
  • April 2006
  • March 2006
  • February 2006
  • January 2006
  • December 2005
  • November 2005
  • October 2005
  • September 2005
  • August 2005
  • July 2005
  • June 2005
  • May 2005
  • April 2005
  • March 2005
  • February 2005
  • January 2005
  • December 2004
  • November 2004
  • October 2004
  • September 2004
  • August 2004
  • July 2004
  • June 2004
  • May 2004
  • April 2004
  • March 2004
  • February 2004
  • January 2004
  • December 2003
  • November 2003
  • October 2003
  • September 2003
  • August 2003
  • July 2003
  • June 2003
  • May 2003
  • April 2003
  • March 2003
mattberther.com © 2003 - 2010