Property changed event on Javascript objects.

Recently I ran across a question on StackOverflow.com. The question was: “Is it possible to have an event that fires when the value of a certain variable changes“. My first reaction was “No… you can’t”. You must create a setter method on your object and pray that the users of your code use the setter method instead of setting the variable itself.

But luckily there are people in this world who are more ingenious than me… it is possible. You must write a little bit of code on the Object-prototype but it is quite self explaining. The code is found here: Eli Grey’s Gist.

I copy/pasted the code here below (changed some formatting). But again… All credits go to Eli Grey.

// object.watch
if (!Object.prototype.watch)
{
    Object.prototype.watch = function (prop, handler)
    {
        var val = this[prop],
        getter = function ()
        {
            return val;
        },
        setter = function (newval) {
            return val = handler.call(this, prop, val, newval);
        };
        if (delete this[prop]) { // can't watch constants
            if (Object.defineProperty) { // ECMAScript 5
                Object.defineProperty(this, prop, {
                   get: getter,
                   set: setter
                });
            }
            else if (Object.prototype.__defineGetter__ &&
                     Object.prototype.__defineSetter__) //legacy
            {
                Object.prototype.__defineGetter__.call(this, prop, getter);
                Object.prototype.__defineSetter__.call(this, prop, setter);
            }
        }
    };
}

// object.unwatch
if (!Object.prototype.unwatch)
{
    Object.prototype.unwatch = function (prop) {
        var val = this[prop];
        delete this[prop]; // remove accessors
        this[prop] = val;
    };
}

That’s it… works great…

Happy Coding…

Converting a negative Integer to String with leading zeros

Quick post for today.

While doing some refactoring I ran into the following code which was intended to convert a negative integer to a string with leading zeros.

int value = GetValue();
string val = "-" + (value * -1).ToString().PadLeft(2, '0');

This can be done much easier. And it works for positive and negative integers. Check the improved code below.

int value = GetValue();
string val = value.ToString("D2");

For a complete list of the possibilities for converting a integer into an string check the MSDN website for Standard Numeric Format Strings:

Happy coding…

Hierarchical Ordering – Dependency Walker

Recently I ran into some challenging moments trying to reorder some classes which had an hierarchical order. Implementing the IComparable<T> interface and calling the Sort method on the List<T> just wasn’t enough. This was caused by the fact that the CompareTo method doesn’t know anything about the nested hierarchy.

The problem described above emerged when I was working with OpenLayers. We have made a lot of changes to OpenLayers and therefore I do not use the merged OpenLayers file but the separate source files. OpenLayers comes with a Python build script which orders the sourcefiles (based on it’s hierarchy) and compresses it to one file. Due to some circumstances the standard OpenLayers build script had to be changed significantly. The changes where bigger than my knowledge of Python and therefore I decided to make a .NET builder which will do the same thing as the Python script but with my changes in it.  And then I ran into the problem with the correct order of files.

OpenLayers files has a ‘@ reguires’ commentline in it’s files which determines the dependency between the files. I started to create a class which represents the OpenLayers file:

internal class OpenLayersFile: IComparable<OpenLayersFile>
{
    public OpenLayersFile(string filename)
    { ... }

    public string Name { get; set; }
    public List<string> DependsOn { get; set; }
    public int CompareTo(OpenLayersFile otherFile)
    { ... }
}

The class was simple. It has a Name – property which is the concatenated name of the file (e.g. OpenLayers/Layer/WMS.js). and a DependsOn – property which is a list of “Names” of the files it depends on. The CompareTo method just does a check if DependsOn contains the Name of the file it’s compared to. The logic is omitted because it will clutter up the code snippet and doesn’t add value to this post.

Because List<T>.Sort() didn’t work as described expected as described above I created my own Dependency Walker which runs down all the files and orders them correctly. This dependency walker also keeps in mind to order correct when we have a baseclass with a baseclass which has a baseclass (and so on). Here is the code:

private static class DependencyWalker
{
     public static void Walk(List<OpenLayersFile> files)
     {
          for (int index = 0; index < files.Count; index++)
          {
              OpenLayersFile fileToCompare = files[index];
              for (int i = 0; i < index; i++)
              {
                  OpenLayersFile otherFile = files[i];
                  if (fileToCompare.CompareTo(otherFile) == -1)
                  {
                      files.Remove(fileToCompare);
                      files.Insert(i, fileToCompare);
                      index = 0;
                      break;
                   }
                }
           }
      }
}

This worked perfectly for me and I hope that it will help you too. I am also interested if you have a different solution to the problem. If so, please contact me.

Happy coding!

ComVisible class with a non ComVisible baseclass

In my previous post I was talking about using the WebBrowserControl in a WinForms application. I demonstrated how you can communicate to the JavaScript of the webpage loaded in the WebBrowserControl in your C# code and vice versa.

While using this code I ran into a problem myself. The Form which was made ComVisible had a baseclass which was not ComVisible. When I ran my code I had this great exception when calling the C# code from JavaScript:

NonComVisibleBaseClass was detected
A QueryInterface call was made requesting the default IDispatch interface of COM visible managed class ‘JYAG.WebControlInWinforms.GeekBrowser’. However since this class does not have an explicit default interface and derives from non COM visible class ‘JYAG.WebControlInWinforms.GeekBasePage’, the QueryInterface call will fail. This is done to prevent the non COM visible base class from being constrained by the COM versioning rules.

The simplest solution  is to make the baseclass ComVisible just as well. But in my case it was not an option to expose the baseclass to Com-components. So what can we do to make this work without having to make the baseclass ComVisible.  There are three easy steps to take to accomplish this.

Step 1 – Define a interface with the methods you’d like to call from JavaScript

First we define a Interface and put all the methods we want to reach through JavaScript in there. We make the interface ComVisible. I took the test-project of my previous post and added a IMapControlInteractable interface which contains just one method.

    [ComVisible(true)]
    public interface IMapControlInteractable
    {
        void ActivateControls();
    }

Step 2 – Give the ComVisible class the ClassInterfaceAttribute

To use the Interface in combination with the ComVisible attribute and effectivly let the JavaScript communicate with the C# code we give the class the ClassInterfaceAttribute and specify the type at ‘none’.

    [ClassInterface(ClassInterfaceType.None)]

Step 3 – Implement the Interface

The last thing we must do is implement the Interface. If we do so the code my look something like this.

    //Make class visible for COM so we can set the ObjectForScripting
    //Specify ClassInterfaceType.None to use the ComVisible Interface
    [ComVisible(true)]
    [ClassInterface(ClassInterfaceType.None)]
    public partial class GeekBrowser : GeekBasePage, IMapControlInteractable
    {

That’s all there is to it. Now our exception at runtime disappears and our code works. And our baseclass is not ComVisible.

Download this code in the adjusted test project.

For comments, questions  or suggestions contact me or leave a comment below.

Winforms with a WebBrowserControl, Fun with ObjectForScripting

Recently I had to put a map control (like Google Maps) in a Winforms application and I had to make the map control react on actions performed on the Winform. I discovered that this was very easy and fun to do with the ObjectForScripting.

In this post I will explain the basics of how to work and communicate with a WebBrowserControl in a Winforms application. I have made a test project which you can download so you can see the magic in action. Because I want to show you the basics of the ObjectForScripting I kept the project as simple as possible. No fancy code-patterns… just straightforward coding.

The idea of the project is:

  • The Winform has several input fields for personal information which are all disabled
  • A button on a webpage in the WebBrowserControl activates the input fields of the Winform
  • The Winform contains a button which transfers the values of the input fields on the Winform to the input fields of a webpage

By implementing this in my project I can demonstrate the communication from Webpage to Winform (activating the controls on the Winform) as well as the communication from Winform to the Webpage (filling the input fields). Download the project and examine it carefully.

So now look at the code
Read more