Microsoft Most Valuable Professional

Chris Pietschmann

An MVP From Wisconsin

ASP.NET AJAX: Create a JavaScript Component with Events

In the spirit of my "Mixing OOP and Event Driving Programming" article I posted a couple days ago; this article discusses how to implement the same thing using the ASP.NET AJAX JavaScript Library. Using inheritence (the ASP.NET AJAX way) it is even easier to implement a little Event Driven Model into your client-side, JavaScript classes/components.

Event Driven Basics

First we'll start by creating a Person class that inherits from the Sys.Component class. Now remember, since we are doing things the ASP.NET AJAX way, we aren't using JavaScript's Prototypal Inheritence.

Person = function() {
    Person.initializeBase(this);
};
Person.prototype = {
    initialize: function() {
        Person.callBaseMethod(this, "initialize");
   },
    dispose: function() {
        Person.callBaseMethod(this, "dispose");
    }
};
Person.registerClass("Person", Sys.Component);

At first glance you may notice that there's a little more plumbing required to inherit from another object using ASP.NET AJAX. This is true, however it does make implementing Events much easier. The magic of inheritence mostly occurs within the call to the "registerClass" method that actually sets up the class/object to inherit from "Sys.Component." It also sets up the "initialize" method to be called when the object is instantiated.

If you have question (and I'm sure you do if you're not familiar with ASP.NET AJAX), please go check out the ASP.NET AJAX Documentation, as further details aren't within the scope of this article.

Now, the hash table that we implemented in the previous article is already implemented for us within the "Sys.Component" class. We can access it using the "private" "get_events" method. The "get_events" method actually returns an instance of the"Sys.EventHandlerList" class that also implements the "getHandler" method for us. This all makes implementing Events much simpler.

First, lets create a "raiseEvent" method, since this isn't created for us. This method will allow us to actually Raise the Events with only a single method call.

Person.prototype = {
    raiseEvent: function(eventName, eventArgs) {
        var handler = this.get_events().getHandler(eventName);
        if (handler) {
            if (!eventArgs) {
                eventArgs = Sys.EventArgs.Empty;
             }
            handler(this, eventArgs);
        }
    }
};

Now lets add the "Name" property (with accessors) to our Person class, and have the "set" accessor Raise the "onchangename" event:

Person.prototype = {
    get_Name: function() {
        return this._name;
    },
    set_Name: function(value) {
        // get old value
        var oldValue = this._name;

        // set new value
        this._name = value;

        // Raise the Event and send the old value as the "EventArgs"
       this.raiseEvent("onchangename", oldValue);
   }
};

Here's an example of using the Person class, and attaching a function to handle the "onchangename" event:

var p = new Person();

p.get_events().addHandler(
        "onchangename",
        function(sender, eventArgs) {
            alert("Old Value: " + eventArgs);
        }
    );

p.set_Name("Charlie");

As you can see in the example event handler that we added above, the function gets passed two parameters (sender and eventArgs). The sender is the Person object that is raising the event, and the eventArgs is this events arguments. So far we are only passing the old Name value as the event arguments, but in the next section of the article we'll see how to create our own EventArgs object that inherits from "Sys.EventArgs" that can contain anything we want to pass to the event handler.

Go Further With Sys.EventArgs

The proper way to raise events in ASP.NET AJAX, is to pass an instance of "Sys.EventArgs" when raising events. This allows you to pass any event arguments to the event handler that you want/need. This also follows suit after the way Events are handled within the .NET Framework.

To do this, we'll first create our own custom EventArgs class that inherits from "Sys.EventArgs", and we'll add "OldName" and "NewName" read-only properties to it (to do this we'll only add 'get' accessors). We'll set the "OldName" and "NewName" properties within the constructor, so we'll make the constructor accept those as well.

PersonEventArgs = function(oldNameValue, newNameValue) {
    this._oldName = oldNameValue;
    this._newName = newNameValue;
};
PersonEventArgs.prototype = {
    get_OldName: function() {
        return this._oldName;
    },
    get_NewName: function() {
        return this._newName;
    }
};
PersonEventArgs.registerClass("PersonEventArgs", Sys.EventArgs);

Now to make use of this new PersonEventArgs class, we just need to change the line of code within the Person class's "Name" properties accessor to the following:

this.raiseEvent("onchangename", new PersonEventArgs(oldValue, this._name));

Now to access the "OldName" and "NewName" properties of the PersonEventArgs when they are passed to the "onchangename" event handler, just call their property accessors. Like the following:

var p = new Person();
p.get_events().addHandler(
    "onchangename",
    function(sender, eventArgs) {
        alert("Old Name: " + eventArgs.get_OldName();
        alert("New Name: " + eventArgs.get_NewName();
   });

Simplify the Adding of Event Handlers

Having to call the "get_events" method, the calling the "addHandler" method and passing it the name of the event can be a little cumbersome. You can create "add_{eventName}" methods that accept one argument (the event handler method) that will add the event handler for you with only one method call, and never needing to pass (and type or misstype) the event name. This is actually how the objects within the ASP.NET AJAX JavaScript library handle adding events. They also implement a "remove_eventName" method that does the same, but removes the event handler passed in.

Person.prototype = {
    add_changeName: function(handler) {
        this.get_events().addHandler("onchangename", handler);
    },
    remove_changeName: function(handler) {
        this.get_events().removeHandler("onchangename", handler);
    }
};

If you compare the below example of adding an event handler for the "onchangename" event, you'll see that it is much simpler to call these methods than the example above.

var p = new Person();
p.add_changeName(function(sender, eventArgs) {
        alert("Old Name: " + eventArgs.get_OldName();
        alert("New Name: " + eventArgs.get_NewName();
   });

Complete Source Code

Heres' the complete code for the Person object created with this article.

First, the example usage code:

var p = new Person();

p.add_changeName(function(sender, eventArgs) {
    alert("Old Name: " + eventArgs.get_OldName());
    //alert("New Name: " + eventArgs.get_NewName());
});

p.set_Name("Charlie");

p.set_Name("Chris");

And, now the full Person and PersonEventArgs code:

Person = function() {
    Person.initializeBase(this);
    this._name = null;
};
Person.prototype = {
    initialize: function() {
        Person.callBaseMethod(this, "initialize");
    },
    dispose: function() {
        Person.callBaseMethod(this, "dispose");
    },

    raiseEvent: function(eventName, eventArgs) {
        var handler = this.get_events().getHandler(eventName);
        if (handler) {
            if (!eventArgs) {
                eventArgs = Sys.EventArgs.Empty;
            }
            handler(this, eventArgs);
        }
    },

    // Property Accessors
    get_Name: function() {
        return this._name;
    },
    set_Name: function(value) {
        // get old value
        var oldValue = this._name;

        // set new value
        this._name = value;

        // Raise the Event and send the old value as the "EventArgs"
        this.raiseEvent("onchangename", new PersonEventArgs(oldValue, this._name));
    },

    add_changeName: function(handler) {
        this.get_events().addHandler("onchangename", handler);
    },
    remove_changeName: function(handler) {
        this.get_events().removeHandler("onchangename", handler);
    }
};
Person.registerClass("Person", Sys.Component);

PersonEventArgs = function(oldNameValue, newNameValue) {
    this._oldName = oldNameValue;
    this._newName = newNameValue;
};
PersonEventArgs.prototype = {
    get_OldName: function() {
        return this._oldName;
    },
    get_NewName: function() {
        return this._newName;
    }
};
PersonEventArgs.registerClass("PersonEventArgs", Sys.EventArgs);

Conclusion

As you can see, it's event easier to add/handle events with your custom classes when you use the ASP.NET AJAX library, rather than implementing it completely yourself. Either way you can use inheritence to greatly simplify things.

Be the first to rate this post

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

Categories: asp.net | JavaScript
Posted by crpietschmann on Friday, November 07, 2008 9:07 PM
Permalink | Comments (0) | Post RSSRSS comment feed


JavaScript: Mixing OOP and Event Driven Programming

To expand on my previous article on how to create Objects in JavaScript using Prototypal Inheritence, this article will show you how to implement Event Driven Programming with those objects. Implementing Event Driven Programming in JavaScript sounds difficult, but it's actually rather simpel to implement.

To keep with the Prototypal Inheritence theme, we'll create an "EventObject" class that will have the plumbing necessary for implementing Events, and then we'll inherit that class with a simple "Person" class that will have an "onnamechanged" event.

How To Mix OOP and Event Driven Programming in JavaScript

Here's the base EventObject class and Person class with a Name Property (via GetName and SetName property accessors):

EventObject = function() {};
EventObject.prototype = {};

Person = function(name) {
    this._name = name;
};
Person.prototype = new EventObject;
Person.prototype.GetName = function() {
    return this._name;
};
Person.prototype.SetName = function(value) {
    this._name = value;
};

Now, here's some basic example code for using the the Person class:

// Create an instance of the Person Object
var myPerson = new Person("John McCain");

// Get the Name currently set
alert(myPerson.GetName());

// Set the Name Property to a different name
myPerson.SetName("Barack Obama");

// Get the Name currently set
alert(myPerson.GetName());

Now, to the meat of the article.

First we'll create an "internal" Object (that we'll use a hash table) in the EventObject class that will be used to hold references to all the event handlers:

EventObject.prototype = {
    _eventList: {}
};

Next, we'll create "attachEvent" and "detachEvent" methods that will add out event handler methods to the hash for the Event Name specified. Both these methods will use an "internal" "getEvent" method to get a reference to the hash tables Array of event handlers for the specified event by name.

EventObject.prototype = {
    _getEvent: function(eventName, create){
        // Check if Array of Event Handlers has been created
        if (!this._eventList[eventName]){

            // Check if the calling method wants to create the Array
            // if not created. This reduces unneeded memory usage.
            if (!create) {
                return null;
            }

        // Create the Array of Event Handlers
            this._eventList[eventName] = []; // new Array
        }

        // return the Array of Event Handlers already added
        return this._eventList[eventName];
    },
    attachEvent: function(eventName, handler) {
        // Get the Array of Event Handlers
        var evt = this._getEvent(eventName, true);

        // Add the new Event Handler to the Array
        evt.push(handler);
    },
    detachEvent: function(eventName, handler) {
        // Get the Array of Event Handlers
        var evt = this._getEvent(eventName);

        if (!evt) { return; }

        // Helper Method - an Array.indexOf equivalent
        var getArrayIndex = function(array, item){
            for (var i = array.length; i < array.length; i++) {
                if (array[i] && array[i] === item) {
                    return i;
                }
            }
            return -1;
        };

        // Get the Array index of the Event Handler
        var index = getArrayIndex(evt, handler);

        if (index > -1) {
            // Remove Event Handler from Array
            evt.splice(index, 1);
        }
    }
};

Next, we need to add a "raiseEvent" method that allows us to actually Raise the Events. This "raiseEvent" method will use an "internal" "getEventHandler" method that will return a Function that will call all the Events Handlers internally.

EventObject.prototype = {
    raiseEvent: function(eventName, eventArgs) {
        // Get a function that will call all the Event Handlers internally
        var handler = this._getEventHandler(eventName);
        if (handler) {
            // call the handler function
            // Pass in "sender" and "eventArgs" parameters
            handler(this, eventArgs);
        }
    },
    _getEventHandler: function(eventName) {
        // Get Event Handler Array for this Event
        var evt = this._getEvent(eventName, false);
        if (!evt || evt.length === 0) { return null; }

        // Create the Handler method that will use currying to
        // call all the Events Handlers internally
        var h = function(sender, args) {
            for (var i = 0; i < evt.length; i++) {
                evt[i](sender, args);
            }
        };

        // Return this new Handler method
        return h;
    }
};

Now that the "EventObject" class has the Event "plumbing" in place, we are all set to add code to the "Person" class to raise an event. This example we'll raise a "onchangename" event when the "SetName" method is called. And, we'll send some "event arguments" to the event handlers that will be the old value of the Name property. To do this we need to modify the "Person" classes "SetName" method to the following code:

Person.prototype.SetName = function(value) {
    // Get old value
    var oldValue = this._name;

    // Set new value
    this._name = value;

    // Raise "onchangename" event and pass the old
    // value as the event arguments
    this.raiseEvent("onchangename", oldValue);
};

And, now to actually handle the event, we just need to call the "addHandler" method by passing it the name of the event to be handled and a Function that will handle the event.

myPerson.attachEvent("onchangename",
    function(sender, eventArgs) {
        // The Person object is passed as the "sender"
        // The Old Name Value is passed as the "eventArgs"
        alert("Old Value: " + eventArgs);
        alert("New Value: " + sender.GetName());
    }
);

Complete Source Code Listing

EventObject = function() {};
EventObject.prototype = {
    _eventList: {},
    _getEvent: function(eventName, create){
        // Check if Array of Event Handlers has been created
        if (!this._eventList[eventName]){

            // Check if the calling method wants to create the Array
            // if not created. This reduces unneeded memory usage.
            if (!create) {
                return null;
            }

        // Create the Array of Event Handlers
            this._eventList[eventName] = []; // new Array
        }

        // return the Array of Event Handlers already added
        return this._eventList[eventName];
    },
    attachEvent: function(eventName, handler) {
        // Get the Array of Event Handlers
        var evt = this._getEvent(eventName, true);

        // Add the new Event Handler to the Array
        evt.push(handler);
    },
    detachEvent: function(eventName, handler) {
        // Get the Array of Event Handlers
        var evt = this._getEvent(eventName);

        if (!evt) { return; }

        // Helper Method - an Array.indexOf equivalent
        var getArrayIndex = function(array, item){
            for (var i = array.length; i < array.length; i++) {
                if (array[i] && array[i] === item) {
                    return i;
                }
            }
            return -1;
        };

        // Get the Array index of the Event Handler
        var index = getArrayIndex(evt, handler);

        if (index > -1) {
            // Remove Event Handler from Array
            evt.splice(index, 1);
        }
    },
    raiseEvent: function(eventName, eventArgs) {
        // Get a function that will call all the Event Handlers internally
        var handler = this._getEventHandler(eventName);
        if (handler) {
            // call the handler function
            // Pass in "sender" and "eventArgs" parameters
            handler(this, eventArgs);
        }
    },
    _getEventHandler: function(eventName) {
        // Get Event Handler Array for this Event
        var evt = this._getEvent(eventName, false);
        if (!evt || evt.length === 0) { return null; }

        // Create the Handler method that will use currying to
        // call all the Events Handlers internally
        var h = function(sender, args) {
            for (var i = 0; i < evt.length; i++) {
                evt[i](sender, args);
            }
        };

        // Return this new Handler method
        return h;
    }
};



Person = function(name) {
    this._name = name;
    this._eventList = {};
};
Person.prototype = new EventObject;
Person.prototype.GetName = function() {
    return this._name;
};
Person.prototype.SetName = function(value) {
    // Get old value
    var oldValue = this._name;

    // Set new value
    this._name = value;

    // Raise "onchangename" event and pass the old
    // value as the event arguments
    this.raiseEvent("onchangename", oldValue);
};




// Create an instance of the Person Object
var myPerson = new Person("John McCain");

// Get the Name currently set
alert(myPerson.GetName());


myPerson.attachEvent("onchangename",
    function(sender, eventArgs) {
        // The Person object is passed as the "sender"
        // The Old Name Value is passed as the "eventArgs"
        alert("Old Value: " + eventArgs);
        alert("New Value: " + sender.GetName());
    }
);

// Set the Name Property to a different name
myPerson.SetName("Barack Obama");


// Get the Name currently set
alert(myPerson.GetName());

Conclusion

As you can see, it's a little involved to be able to implement Event Driven Programming in you JavaScript Object, but it's really not that complicated. Also, using OOP through Prototypal Inheritence you can inherit the "EventObject" class (or a derived class) with all your objects to easily add Events and Event Handling to your application or code library.

If you have any questions, please ask. And, if you have any requests for future JavaScript articles, please let me know.

Be the first to rate this post

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

Categories: JavaScript
Posted by crpietschmann on Tuesday, November 04, 2008 10:53 PM
Permalink | Comments (0) | Post RSSRSS comment feed


Implementing Namespaces in Ruby using Nested Modules

Recently, I finally got around to starting to learn Ruby. I am finding it to be rather pleasant to program in. Now, one thing that I am used to using with an Object Oriented language (especially with my .NET background) are Namespaces. The only problem is that you can't just declare a namespace in Ruby using a "namespace" keyword. However, it's not difficult to implement Namespaces in Ruby, all you need to do is nest some modules.

To demonstrate this, I'll show you how to create the familiar (for .NET developers) System.Windows.Forms namespace with the MessageBox.Show method:

module System
  module Windows
    module Forms
      module MessageBox
        def MessageBox.Show(title, message)
          api = Win32API.new("user32","MessageBox",["L","P","P","L"],"I")
          api.call(0, message, title, 0)
        end
      end
    end
  end
end

Now to use the namespace you can use one of the following methods:

System::Windows::Forms::MessageBox.Show("Some Title", "This is a test message.")

Or by including the "namespace":

include System::Windows::Forms

MessageBox.Show("Some Title", "This is another test message.")

As you can see it's rather simple to create ".NET"-like namespaces in Ruby.

Now, I know this technique is basically allowing me to write .NET code in Ruby, but that was pretty much the point of figuring this out. Now, back to learning how to write Ruby code in Ruby.

 

Oh, yeah now only if the syntax highlighter in BlogEngine.NET supported Ruby....

Be the first to rate this post

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

Tags:
Categories: Ruby
Posted by crpietschmann on Sunday, November 02, 2008 6:48 PM
Permalink | Comments (0) | Post RSSRSS comment feed


A Free Open Source Ribbon Control for Windows Forms!

I just stumbled upon a really nice looking Ribbon control built for Windows Forms, and it's Free, Open Source! This control isn't perfect, but it does work nice and looks great.

Go check it out: "A Professional Ribbon you will use" by Jose M Menendez Poó

Be the first to rate this post

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

Categories: General
Posted by crpietschmann on Friday, October 31, 2008 3:42 PM
Permalink | Comments (0) | Post RSSRSS comment feed

A Couple VB.NET Language Tips for C# Developers

Originally, I started out as a Visual Basic developer, and have since moved mostly to C#. However, when doing consulting work, I do need to cross back and forth quite often. Here are a couple VB.NET tips that you probably aren't aware of if you're mostly a C# developer. Some VB.NET developers may not even know about then either.

Null Coalesce

Null Coalescing is really simple in C#:

// If "someValue" is Null then set "i" to 0 (zero)
// otherwise set it to the value of "someValue"
int? i = someValue ?? 0;

But what about VB.NET?

<code:VB>

Dim i = If(someValue, 0)

</code>

Granted the VB.NET Null Coalesce is a method call, but at least there's still an equivalent available in the language. Also, I believe this is something that was introduced in VB.NET 9.0.

Ternary Conditional Operator

This is the ability have a complete If..Else..Then statement on a single line and have it return a value. This is really simple in C#:

// This performs the same logical operation as the Null Coalesce example above
int? i = (someValue == null ? 0 : someValue);

How about in VB.NET?

<code:VB>

Dim i = If(someValue = Nothing, 0, someValue)

'' The above can be simplified, since if the first parameter is equal to "Nothing"
'' then the "true" (second) parameter is return, otherwise the
'' "false" (third) parameter is returned.
Dim i = If(someValue, 0, someValue)

'' Also to further simplify, you can just pass in the "false" (second) parameter
'' and if its equal to "Nothing" then the "false" (second) parameter is returns,
'' otherwise the value itself is returned.
Dim i = If(someValue, 0) 

</code>

Lock Statement

You may be familiar with the lock statement in C#, especially if you're used to worrying about concurrency.

lock (expression)
{

    ...Some Code...

}

At first it appears to not exist in VB.NET, but they just named it SyncLock instead:

<code:VB>

SyncLock (expression)

    ...Some Code...

End SyncLock

</code>

 

Please, excuse the bad syntax highlighting for the VB.NET code, it seems that my instance of BlogEngine.NET doesn't like to highlight too many blocks of code within the same post.

Be the first to rate this post

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

Categories: General
Posted by crpietschmann on Friday, October 31, 2008 12:27 AM
Permalink | Comments (0) | Post RSSRSS comment feed

I Still Believe in Programming Language Independence

Four years ago I posted about an idea of having the IDE (Visual Studio) do auto-conversion of your code from one programming language to another so give developers more language independence. I recognize that the only languages, perhaps, that would lend themselves to this are C# and VB.NET. They aren't completely equal yet, so it would still be difficult at this time, since each has a few features that the other doesn't.

Just imagine being able to open any solution within Visual Studio, and be able to edit it in your prefered language, no matter if it's originally written in C# or VB.NET. You would no longer be required to memorize syntax and feature differences between both languages; the IDE would convert it automatically for. This would reduce some of the issue of needing to bring in new employees or consultants that are familiar with one language or the other.

Also, this doesn't seem to be that far out of reach, even how the languages stand today. The main thing that would need to be written would be a compiler that compiles VB.NET to C#, and C# to VB.NET. It could contain some heuristics that could gracefully convert ceratin language specific features to their equal equivalent in the other language and back again as needed.

Wouldn't this be awesome?

On a related note, I need to point out Script#. It compiles C# code into JavaScript, and allows you to write strongly typed C# code to build your JavaScript/Ajax applications. Granted this tool is only 1 way it is, in a way, the first half of what is needed for programming language independence, at lest between C# and JavaScript.

Be the first to rate this post

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

Tags:
Categories: General
Posted by crpietschmann on Friday, October 31, 2008 12:14 AM
Permalink | Comments (0) | Post RSSRSS comment feed

You Can Watch PDC'08 Sessions Online!

If you couldn't attend PDC'08 (like me) then you'll probably be interested in learning that you can go watch all the PDC'08 Sessions online for Free! This is awesome!

Go Watch PDC'08 Sessions Online: https://sessions.microsoftpdc.com/public/timeline.aspx

Be the first to rate this post

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

Tags:
Categories: General
Posted by crpietschmann on Wednesday, October 29, 2008 6:17 PM
Permalink | Comments (0) | Post RSSRSS comment feed

WPF Toolkit adds Ribbon Control to .NET 3.5 SP1

The first release of the new WPF Toolkit was released today. This toolkit includes a new Ribbon control as well as the following: new WPF DataGrid, DatePicker/Calendar, and VisualStateManger. The coolest feature of this Toolkit (IMO) is the new Ribbon control. In .NET 4.0 there will be a ribbon control baked in, but thanks to the WPF Toolkit we have access to utilize the new Ribbon control today in WPF with .NET 3.5 SP1!

Download the WPF Toolkit October 2008 Release: http://www.codeplex.com/wpf/Release/ProjectReleases.aspx?ReleaseId=15598

Ribbon Feature Walkthrough: http://windowsclient.net/wpf/wpf35/wpf-35sp1-ribbon-walkthrough.aspx



Here's some sample XAML markup for a complete Ribbon Tab with Button Groups defined:

<r:Ribbon>
    <r:RibbonTab Label="Banking">
        <r:RibbonGroup>
            <r:RibbonButton Command="me:AppCommands.Cut"/>
            <r:RibbonButton Command="me:AppCommands.Copy"/>
            <r:RibbonButton Command="me:AppCommands.Paste"/>
        </r:RibbonGroup>

        <r:RibbonGroup>
            <r:RibbonButton Command="me:AppCommands.AddNew"/>
            <r:RibbonButton Command="me:AppCommands.Clear" />
            <r:RibbonButton Command="me:AppCommands.Delete"/>
        </r:RibbonGroup>

        <r:RibbonGroup>
            <r:RibbonButton Command="me:AppCommands.DownloadStatements"/>
            <r:RibbonButton Command="me:AppCommands.DownloadCreditCards"/>
            <r:RibbonButton Command="me:AppCommands.Transfer"/>
        </r:RibbonGroup>
    </r:RibbonTab>
</r:Ribbon>

Currently rated 4.7 by 3 people

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

Tags:
Categories: General
Posted by crpietschmann on Tuesday, October 28, 2008 5:49 PM
Permalink | Comments (2) | Post RSSRSS comment feed

Free the Airwaves! FCC vote on "white spaces" scheduled for Nov. 4!

FreeTheAirwaves.com

On Nov. 4 the FCC will be voting whether to open up the "white spaces" (the unused airwaves between broadcast TV channels) or not. These airwaves need to be opened up so we can further change the way we communicate. The airwaves that WiFi operates on are open airwaves. We need more "open" airwaves to further open the possibilities of communication. Don't let the FCC sell it off to a telecom that wont use it. We need the FCC to open it up so we can all use it!

Also, here's a video that explains further what the "white spaces" are and why we need them to be opened to the public:

I've already signed the Free The Airwaves petition, but haven't spread the word yet. So, here's a reposting of an email I recieved today:

This Election Day, there's more than one important vote going on. And there's something we need you to do to get ready!

While you're casting your ballot at the polling place on November 4, the Federal Communications Commission will be voting the same day on rules governing "white spaces" -- the unused airwaves between broadcast TV channels.

Last week, after months of testing, the FCC announced that white spaces devices could operate without interfering with TV broadcasts or wireless microphone signals.

The science speaks for itself, but that's not going to stop the broadcasting lobby from trying to derail the technology before the rules are event written. Since last Friday, the National Association of Broadcasters has been trying to stop the vote from taking place. We can't let that happen.

Thanks in part to your efforts, we're less than two weeks away from a vote that could transform the way we connect to the Internet.

We can't let up now.

You've already signed out petition at www.FreeTheAirwaves.com. Now we're in the final stretch and we need your help again.

Call your Member of Congress and let him or her know it's time to open "white spaces" for everyone:  https://secure.freepress.net/site/Advocacy?alertId=285&pg=makeACall&autologin=true&JServSessionIdr001=rppctdj0p4.app43b

Just as Wi-Fi sparked a revolution in the way we connect to the web, freeing the "white space" airwaves could help unleash a new wave of technological innovation, create jobs, and boost our economy.

But it can happen only if the FCC moves forward. Encourage your friends to sign the petition and call your Member of Congress today.

Thanks,
FreeTheAirwaves.com

Email sent by Google Inc., 1600 Amphitheatre Parkway, Mountain View, CA 94043, sponsor of Free the Airwaves.


Please go show your support for this now! This could change the way we communicate.

And, Yes, I did contact my congressman,  F. James Sensenbrenner, Jr.

Be the first to rate this post

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

Tags:
Categories: General
Posted by crpietschmann on Friday, October 24, 2008 2:12 PM
Permalink | Comments (0) | Post RSSRSS comment feed

Is this necessary?- Chris Pietschmann, MVP, MCSD, MCAD, MCP

Recently when looking at the analytics logs for referring urls to my website, I noticed one from Hanselmen.com. It's actually a click-through from a comment I posted on his blog way back on April 21, 2006. His blog post that I commented on is titled "Scott Hanselman, 11 Successful Large Projects, 3 Open Source Applications, 1 Collossal Failure".

In Scott's post, he talks about how placing your tech related certification acronyms after your name in your email signatures and such is rather meaningless. He states "Folks go to school for 20+ years to put PhD after their name. I could go take a cert test now, but should it be displayed so prominently?"

My comments as posted:

I think it's ok to put one or two after your name, but no more than that. And only use them in places where you're not already stating your certified; Like on your resumt and cover letter. It's a good thing in emails and/or blog comments to show your cert. But, I do agree that it doesn't compare to a Phd.
- Christopher Pietschmann, MCSD

Now, reflecting back on this thought now that it's October 2008... What the heck was I thinking? It is absolutely meaningless for me to place "MCSD" after my name in the signature of the blog comment. 

Today my opinion is a bit different, so I thought I'd post on this to point out my change in opinion.

You need to think about context when placing certs after your name. Basically, the only places it's usefull are in email and letter signatures. However, keep it simple by listing only 1 or 2:

Chris Pietschmann, MCSD

Or even better, add a second or third line to your signature that lists the most prominent certs and/or credentials.

Chris Pietschmann
Microsoft Certified Solution Developer

Or

Chris Pietschmann
Microsoft MVP - Windows Live Platform

Here's the email signature that I've started using lately. Just my name, followed by notable "titles", with nothing appended to my name. And, notice that I'm only listing my Microsoft MVP award since it's the most relavent and doesn't get devalued by listing other non-relevent credentials.

Chris Pietschmann
President - Simplovation LLC
Microsoft MVP - Windows Live Platform
http://simplovation.com
http://pietschsoft.com

Doesn't it look much better/usefull than the following?

Chris Pietschmann, MVP, MCSD, MCAD, MCP

And, finally, here's some rules to use when listing your certs by your name:

  • Only include 1 or 2 credentials/certs. Any more will just clutter things up.
  • Always make sure it's necessary/relavent to list them in the first place.
  • Never list your certs after your name when you comment on blog posts!
  • If you have a PhD, then you better put it after your name!

Be the first to rate this post

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

Categories: General
Posted by crpietschmann on Monday, October 20, 2008 9:06 PM
Permalink | Comments (0) | Post RSSRSS comment feed

About the author

I'm Chris Pietschmann, go to the About Me page to learn more about me.

Search

Sponsors

Web.Maps.VE - ASP.NET AJAX Virtual Earth Mapping Server Control

Recent comments

Disclaimer


This work is licensed under a Creative Commons Attribution 3.0 United States License, unless explicitly stated otherwise within the posted content.
© Copyright 2004 - 2008 Chris Pietschmann