About the author

Chris Pietschmann is an Independent Software Consultant and the President/Founder of Simplovation LLC. He is a Microsoft MVP for the Virtual Earth product, and is also on the Executive Committee of the Wisconsin .NET Users Group.
E-mail me Send mail

 

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

Hyper-V Compatibility Check Tool for AMD Processors

I just found that AMD has a tool titled "AMD-V Technology and Microsoft Hyper-V System Compatibility Check Utility". You can run this tool on Windows Vista or Windows Server 2008 (make sure you run it with elevated privileges) to see if your hardware combination of AMD Processor and Motherboard support Hyper-V.

I guess this would have saved me from the trouble of installing Win 2008 with Hyper-V just to figure out that my AMD Athlon 64 X2 4200+ supports Hyper-V, but my motherboard doesn't.

I ran this tool on my system (AMD Athlon 64 X2 4200+ processor with a Gigabyte GA-M55SLI-S4 motherboard) to see what it says, and here's the results it displayed:

Test Results from Microsoft Hyper-V compatibility check for systems with AMD processors
This system is not compatible with Hyper-V.
This utility detected that a necessary BIOS patch is not installed.
Please contact your system vendor to determine whether a BIOS upgrade is available.
If so, upgrade your BIOS and re-run the utility.
If not, consider upgrading to a new AMD64 system to get the latest in virtualization capabilities, performace, and power efficiency.
AMD's most current processors do not require a BIOS patch to run Hyper-V.

So, basically my processor supports hardware assisted virtualization (which I knew), but my motherboard doesn't. Now I just need to check Gigabyte to see if they have a BIOS update available for this motherboard that will enable support for hardware assisted virtualization.

Be the first to rate this post

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

Categories: General
Posted by crpietschmann on Friday, May 16, 2008 10:44 AM
Permalink | Comments (1) | Post RSSRSS comment feed

.NET 3.5 SP1: A Service Pack or The Real .NET 3.5

Microsoft just RTM'd Visual Studio 2008 and .NET 3.5 last November and launched them in February. And, their already releasing a Service Pack? What could they possibly have to all fix in a Service Pack this soon? Well, actually they aren't just fixing stuff; they are adding a huge amount of functionality too. ScottGu has a long post about what's all in it here.

I'm thinking that .NET 3.5 needed to ship, so they took out everything that just wasn't quite all the way there and are including it in this Service Pack. That's the only way I can explain such a huge service pack (with so many New features) so soon. You know it's nice to have new stuff added, especially in an off cycle release, but at least do it in a way that wont cause any potential confusion.

Ok, here's a simple scenario... I have an application that I'm distributing and I post in the requirements that it supports .NET 3.5 Service Pack 1. Well, to most people (not as techie as I) they see it supports .NET 3.5, and try to run it. Well, guess what? They have .NET 3.5 without SP1 and the app throws an exception and crashes when they try to run it. Because of their undesirable experience they delete my app and never look at it again. Now, only if they would have had SP1 installed, they wouldn't have had any issues.

Well, the first thing you'll probably point out is that I claimed .NET 3.5 SP1 support and they only had .NET 3.5 installed. To the normal person who doesn't know what "Service Pack 1" means, they are the same thing.

Secondly, I could probably include the framework and service pack as part of my installer. This way if they don't have .NET 3.5 or SP1 installed, it will install it when they install the app. Now this would work fine and dandy, just as long as I wasn't just distributing the EXE without an installer, or if I didn't (and my users didn't) mind the installer being 25+ MB.

I'm not sure if you agree with me on this, but there is definitely some potential confusion here. However, I don't think this potential confusion is a big enough issue to warrant calling this release .NET 4.0. That would be much worse, since it's easier to get your sys admins to install a service pack instead of a full release.

Anyway, like I said above, maybe .NET 3.5 SP1 is the .NET 3.5 that was supposed to RTM and ship back in November, but they just didn't have enough time to meet the deadline. And, don't get me wrong, I am look forward to the improvements and new features in this service pack, I just wish we had the final release instead of a Beta. I'm leery about installing a .NET Framework Beta on my workstation.

Ok the rant is over...

Be the first to rate this post

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

Categories: General
Posted by crpietschmann on Thursday, May 15, 2008 10:44 PM
Permalink | Comments (1) | Post RSSRSS comment feed

ASP.NET: Create AJAX Server Controls using the ScriptControl base class

I've been doing a lot with ASP.NET AJAX for almost 2 years now, including my Web.Maps.VE product. So, I've decided to spread some of my knowledge in this area by writing up some articles on things that I've learned and figured out.

As a note, since .NET 3.5 is the "latest and greatest" version of the framework out at the time of this writing, this article targets .NET 3.5. This article also assumes you have a basic understanding of ASP.NET AJAX and JavaScript.

What is ScriptControl?

First, what exactly is ScriptControl? Well, the base class I'm referring to is the System.Web.UI.ScriptControl base class located within the System.Web.Extensions.dll assembly.

The ScriptControl is basically the first building block you want to use to start building out a WebControl (server control) that will have some kind of rich AJAX functionality in the browser. You may have heard of ASP.NET AJAX Control Extenders, especially if you're familiar with the AJAX Control Toolkit, so why would we use ScriptControl instead of creating an ExtenderControl in order to give a control some rich AJAX functionality within the browser? Well, you want to create an ExtenderControl to extend or enhance an existing control with some rich AJAX functionality, and you want to inherit from the ScriptControl class when you are creating a full control that will have some rich AJAX functionality.

According to MSDN the ScriptControl class is:

ScriptControl inherits from the WebControl class and implements the IScriptControl interface. The WebControl class is a base class for ASP.NET Web server controls. The ScriptControl is an abstract class, which you cannot instantiate directly. Instead, you derive a class based on this abstract class.

The ScriptControl base class tests the page for a ScriptManager control during the PreRender stage of the derived control. The ScriptControl base class also makes sure that the derived control calls methods of the ScriptManager control to register script during the Render event. This includes registering ScriptDescriptor objects for the ScriptControl when the Render method is called. The Render method makes sure that ScriptDescriptor objects are not rendered unless the ScriptControl itself is rendered. This enables a ScriptControl to work inside a closed WebPart control.

You can add as many descriptors and types as necessary to any class that you derive from ScriptControl.

 

Basics of Creating Server Controls that Inherit from ScriptControl

When first creating your custom server control you inherit from ScriptControl instead of WebControl like usual. The first thing you'll see is ScriptControl requires you to implement two methods: GetScriptDescriptors and GetScriptReferences. The GetScriptDescriptors method is used to get an enumeration of ScriptDescriptor objects that basically define any of the controls client-side AJAX properties. The GetScriptReferences method is used to get an enumeration of ECMAScript (JavaScript) files that will be loaded on the client-side once the page loads; this is used to basically define any client-side scripts the control will require to run on the client.

Here's a basic stub of a control that inherits from ScriptControl:

public class CustomScriptControl : ScriptControl
{
    protected override IEnumerable<ScriptDescriptor> GetScriptDescriptors()
    {
        throw new NotImplementedException();
    }

    protected override IEnumerable<ScriptReference> GetScriptReferences()
    {
        throw new NotImplementedException();
    }
}

Define ScriptReferences

In the GetScriptReferences method, return an enumeration of the ScriptReference objects to include in the page on the client-side.

Here's a basic example of setting up a ScriptReference that includes a script resource that is embedded within the assembly the CustomScriptControl is contained in:

protected override IEnumerable<ScriptReference> GetScriptReferences()
{
    List<ScriptReference> references = new List<ScriptReference>();
    references.Add(new ScriptReference("CustomScriptControl.CustomScriptControl.js", "CustomScriptControl"));
    return references;
}

When inheriting from ScriptControl you'll generally always have at least one ScriptReference because you need to reference the script that creates the client-side JavaScript representation of your control.

Define ScriptDescriptors

In the GetScriptDescriptors method, return an enumeration of ScriptDescriptor objects that define what properties will be passed down to the client-side JavaScript representation of your control.

The only ScriptDescriptor you need to return in the enumeration is a ScriptControlDescriptor instance that contains all the descriptors for your control.

Here's a basic example of returning a ScriptControlDescriptor without any properties being defined:

protected override IEnumerable<ScriptDescriptor> GetScriptDescriptors()
{
    ScriptControlDescriptor descriptor = new ScriptControlDescriptor(this.GetType().FullName, this.ClientID);
    return new ScriptDescriptor[] { descriptor };
}

What ECMAScript (JavaScript) code is needed?

There is a basic block of JavaScript code that you'll need to include in the ScriptReference that's being defined by the GetScriptReferences method that will define the client-side JavaScript representation of your control. This basic block of code that you include in this script file is the same for all ScriptControls that you'll create.

Here's the basic JavaScript that will define the client-side JavaScript representation of the CustomScriptControl we're using in this example. One thing to remember is that the namespaces and object name in the JavaScript file need to be the same as they are in the server-side .NET code.

Type.registerNamespace("CustomScriptControl");
CustomScriptControl.CustomScriptControl = function(element) {
    CustomScriptControl.CustomScriptControl.initializeBase(this, [element]);
};
CustomScriptControl.CustomScriptControl.prototype = {
    initialize:function() {
        CustomScriptControl.CustomScriptControl.callBaseMethod(this, "initialize");
    },
    dispose:function() {
        CustomScriptControl.CustomScriptControl.callBaseMethod(this, "dispose");
    }
};
CustomScriptControl.CustomScriptControl.registerClass("CustomScriptControl.CustomScriptControl", Sys.UI.Control);
if(typeof(Sys)!=="undefined")Sys.Application.notifyScriptLoaded();

 

Also, in order for the ScriptControl to correctly load the "CustomScriptControl.CustomScriptControl.js" script reference that we're using in this example, we must not forget to define the assemblies embedded resource as a Web Resource, like so:

[assembly: System.Web.UI.WebResource("CustomScriptControl.CustomScriptControl.js", "text/javascript")]

Let's Add a Little "Rich" AJAX Functionality to the Control

Now that we have a basic ScriptControl created, we can start to add out "rich" AJAX functionality to it.

In this article, I'm going to keep things extremely simple, and we're going to do the following:

  1. Pass a Name (type string) property to the client by defining it as a ScriptDescriptor, and displaying it to the user via a JavaScript Alert dialog.

Add the Name Property to the Control

public string Name { get; set; }

Add the ScriptDescriptor for the Name Property

Just modify the GetScriptDescriptors method above to look like the following:

protected override IEnumerable<ScriptDescriptor> GetScriptDescriptors()
{
    ScriptControlDescriptor descriptor = new ScriptControlDescriptor(this.GetType().FullName, this.ClientID);

    // Add our Name property to be passed down to the client
    descriptor.AddProperty("Name", this.Name);

    return new ScriptDescriptor[] { descriptor };
}

Add the Client-Side Name Property that will receive the value

To do this we need to add a "private" like variable to hold the value and property accessor methods to our JavaScript file.

Here's the above JavaScript file with the "private" variable and property accessors added for the Name property:

Display the Name to the User

In this example we're going to display the Name property to the user using a JavaScript Alert within the objects client-side initialize property.

Here's the initialize method modified to include the Alert:

Tips and Tricks

One trick that I've learned that proves useful when creating custom ScriptControls, is to create your own base class that inherits from ScriptControl and extends it to use some custom attributes to make adding ScriptReferences and ScriptDescriptors easier.

Here's what the final server-side code of the CustomScriptControl object would look like when using custom attributes to add the ScriptReferences and ScriptDescriptors:

[ScriptReference("CustomScriptControl.CustomScriptControl.js", "CustomScriptControl")]
public class CustomScriptControl : ScriptControlBase
{
    [ScriptControlProperty]
    public string Name { get; set; }
}

As you can see, the new code for the CustomScriptControl using this base class with custom attributes is much cleaner and easier to read.

Here's the complete code for the ScriptControlBase, ScriptReferenceAttribute and ScriptControlPropertyAttribute objects:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Web.UI;

public class ScriptControlBase : ScriptControl
{
    protected override IEnumerable<ScriptDescriptor> GetScriptDescriptors()
    {
        ScriptControlDescriptor descriptor = new ScriptControlDescriptor(this.GetType().FullName, this.ClientID);

        // Add all the ScriptControls Client-Side Object Properties
        PropertyDescriptorCollection props = TypeDescriptor.GetProperties(this);
        foreach (PropertyDescriptor prop in props)
        {
            ScriptControlPropertyAttribute propAttr = prop.Attributes[typeof(ScriptControlPropertyAttribute)] as ScriptControlPropertyAttribute;
            if (propAttr != null)
            {
                object value = prop.GetValue(this);
                string name = (propAttr.Name != null) ? propAttr.Name : prop.Name;
                if (value != null)
                {
                    descriptor.AddProperty(name, value);
                }
            }
        }

        return new ScriptDescriptor[] { descriptor };
    }

    protected override IEnumerable<ScriptReference> GetScriptReferences()
    {
        List<ScriptReference> references = new List<ScriptReference>();

        // Add all the ScriptControls Client-Side JavaScript References
        object[] scriptReferences = Attribute.GetCustomAttributes(this.GetType(), typeof(ScriptReferenceAttribute), false);
        foreach (ScriptReferenceAttribute r in scriptReferences)
        {
            references.Add(r.GetScriptReference());
        }

        return references;
    }
}

[AttributeUsage(AttributeTargets.Property, AllowMultiple = false)]
public class ScriptControlPropertyAttribute : Attribute
{
    public ScriptControlPropertyAttribute() { }

    public ScriptControlPropertyAttribute(string name)
    {
        this.Name = name;
    }

    public string Name { get; set; }
}

[AttributeUsage(AttributeTargets.Class, AllowMultiple = true)]
public class ScriptReferenceAttribute : Attribute
{
    public ScriptReferenceAttribute(string path)
    {
        this.Path = path;
    }

    public ScriptReferenceAttribute(string name, string assembly)
    {
        this.Name = name;
        this.Assembly = assembly;
    }

    private string _path = null;
    public string Path
    {
        get { return _path; }
        set { _path = value; }
    }

    private string _name = null;
    public string Name
    {
        get { return _name; }
        set { _name = value; }
    }

    private string _assembly = null;
    public string Assembly
    {
        get { return _assembly; }
        set { _assembly = value; }
    }

    public ScriptReference GetScriptReference()
    {
        ScriptReference r = null;

        if (this.Path == null)
        {
            r = new ScriptReference(this.Name, this.Assembly);
        }
        else
        {
            r = new ScriptReference(this.Path);
        }

        return r;
    }
}

Conclusion

As you can see it's fairly simple to get started creating your own custom server controls that inherit from ScriptControl, especially if you use the above ScriptControlBase class along with its ScriptControlPropertyAttribute and ScriptReferenceAttribute attributes.

Download Full Source Code: CreateAJAXServerControlUsingScriptControlBaseClass.zip (33.31 kb)

Be the first to rate this post

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

Categories: asp.net
Posted by crpietschmann on Thursday, May 15, 2008 12:52 AM
Permalink | Comments (0) | Post RSSRSS comment feed

Mono: WinForms finally API complete and Moonlight v1.0 is released

It's been forever since I posted anything about Mono, but this stuff deserves some attention.

Mono's Winforms 2.0 is now API Complete

Yesterday, it was announced that the System.Windows.Forms support in Mono (an open source implementation of the .NET Framework targeting Linux, MacOS, Windows, etc.) has finally reached a state of being API complete. This means the public API for WinForms in Mono is exactly the same as in .NET; with a total of 12,776 methods! The first check-in of WinForms occurred on July 8th, 2004; which means it took almost 4 years to implement.
Original Source: http://tirania.org/blog/archive/2008/May-13.html

First Moonlight Release

On May 13, the Mono guys released the first public release of Moonlight, supporting the Silverlight 1.0 profile for Linux. If you don't know what Moonlight is; Moonlight is an open source implementation of Microsoft's Silverlight for Linux.
Original Source: http://tirania.org/blog/archive/2008/May-13-1.html

I'm excited to see that Mono is making some awesome progress in bringing the greatness that is the .NET Framework to Unix, Linux, MacOS, and other operating systems that are non-Microsoft. Way to go guys!

Be the first to rate this post

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

Posted by crpietschmann on Wednesday, May 14, 2008 4:36 PM
Permalink | Comments (0) | Post RSSRSS comment feed

Windows Server 2008 Hyper-V RC0 and Athlon 64 X2 4200+

I used virtualization through VirtualPC 2007 on this computer, an Athlon 64 X2 4200+ with a Gigabyte GA-M55SLI-S4 motherboard, and it worked perfectly. The Athlon 64 X2 even support Hardware-Assisted Virtualization, so things actually run pretty smooth.

Now I've upgraded to Windows Server 2008 so I can run virtual machines with the new Hyper-V (RC0), but when I try to start any virtual machine it gives me an error saying "The virtual machine could not be started because the hypervisor is not running." What?? I just installed it. Did I miss configuring something?

The error dialog box has a "See details" linke, upon clicking this link it reveals the following information:

The virtual machine could not be started because the hypervisor is not running. The following actions may help you resolve the problem:

1) Verify that the processor of the physical computer has a supported version of hardware-assisted virtualization.

2) Verify that hardware-assisted virtualization and hardware-assisted data execution protection are enabled in the BIOS of the physical computer. (If you edit the BIOS to enable either setting, you must turn off the power to the physical computer and then turn it back on. Resetting the physical computer is not sufficient.)

3) If you have made changes to the Boot Configuration Data store, review these changes to ensure that the hypervisor is configured to launch automatically.

Um, ok... What's the problem. It sounds like it could be any number of things. Well, lets start checking things off the list.

1) Yes, I know my cpu supports hardware-assisted virtualization. AMD's documentation states so, and VirtualPC 2007 was able to use it.
3) Um.. I didn't change anything, so it wont be this.

Ok, it must something to do with option number 2.

Let go check the BIOS settings to make sure it's turned on; which it should be, after all it was working with VirtualPC 2007 just fine. Well, after inspecting my BIOS settings, I discovered that there isn't a setting in my motherboards BIOS to turn it on or off. Hmm... That's interesting.

Time to check for a BIOS update. Well, as it turns out, it doesn't look like Gigabyte has an update for my motherboard that will enable any virtualization features within the BIOS.

Stalemate... I guess I'll have to wait until the final release of Hyper-V or until may Gigabyte puts out a BIOS update for my motherboard.

I'm assuming the final release of Hyper-V wont support my motherboard/cpu configuration, since their main target for Hyper-V is server, but hopefully they take into account the scenario of using virtualization heavily in a development environment where you don't have a "server" class cpu in your machine.

Be the first to rate this post

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

Categories: General
Posted by crpietschmann on Monday, May 12, 2008 12:33 PM
Permalink | Comments (3) | Post RSSRSS comment feed

The Milwaukee Visual Studio 2008 Launch Event is over; but the fun has only begun

Two days ago, May 9th, I attended the {Heroes Happen Here} launch event for VS'08, SQL Server '08 and Windows Server '08 in Milwaukee. There was alot of really great content shown off, and we all got to take away some free software, plus the event was free to attend.

I learned about new technologies like Windows Server 2008 Hyper-V and SoftGrid (which look very interesting, by the way), and I had the chance to talk to some really great people from the .NET developer community in Milwaukee. Milwaukee isn't a tech hub, but there are still some very smart techies around.

I also ran into my "old" (I've only known him for I think 2 years) friend Larry Clarkin, and we recorded a Virtual Earth episode of the podcast he and Dave Bost host; The Thirsty Developer. I was told the episode will be finished and released in the next couple weeks. I'll post about it once it's out.

The {Heroes Happen Here} website stated that attendees would receive free copies of Visual Studio '08, SQL Server '08 and Windows Server '08. Awesome, regular copies of each! Right? Not Trials? Wrong. It's awesome that they gave out copies of the software, but... The Windows Server '08 license they gave out was the Enterprise Edition, however it's only a 1 year trial. And, since SQL Server '08 hasn't RTM'd yet, they gave us the latest CTP. The SQL license makes sense (since it hasn't shipped yet), but the Server 2008 Trial was a bummer. I was hoping to get a regular full license so I could setup Hyper-V on my workstation and use virtualization like crazy. This could be done with the 1 year trial, but we all know what will happen in a year. Now the good thing is the Visual Studio 2008 license is for the Standard edition, no trial here. However, since most devs can do everything they do with the Express Editions of Visual Studio (even me for the most part), I don't see too much benefit here.

All in all, with the above complaints stated, It is freaking awesome that Microsoft gave away that much value of software for FREE! Plus, they threw in a copy of Windows Vista Ultimate w/ SP1, which was very cool indeed.

If any of you haven't attended one of the {Heroes Happen Here} launch events, there are still a few dates to come. Just go to the {Heroes Happen Here} website to see if there's a date left near you.

Now even though I've been using Visual Studio 2008 and .NET 3.5 since it RTM'd, I haven't really gotten into SQL Server 2008, Windows Server 2008 and Hyper-V yet. So the fun has only begun.

Be the first to rate this post

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

Categories: General
Posted by crpietschmann on Sunday, May 11, 2008 8:50 AM
Permalink | Comments (0) | Post RSSRSS comment feed

Virtual Earth: Restrict Map to Specified Viewable Area

This example demonstrates the ability to restrict the viewable area (and impose map boundaries) of a Virtual Earth map to be within a specified distance from the maps original center point (at time of initial load), and restrict to a maximum zoom level.

Why might you want to do this? There are times when you may want to restrict your users from possibly getting "lost" when viewing your data on a map. Also, you may want to restrict the user from panning around the globe in an attempt to reduce the number of Virtual Earth Map Transactions that you'll end up paying for. Whatever the reasoning is; I've actually had this functionality requested a few times by clients, so I thought I'd write up a simple example.

This article was written with Virtual Earth v6.1, and will also work with Virtual Earth v6.0.

Download the Code:

VE_RestrictMapSpecifiedViewableArea.zip (3.01 kb)

Other Code Used In This Example

This example utilizes code that was included in the following two examples I've previously written:
Calculate Distance Between Geocodes in C# and JavaScript
Virtual Earth: Draw a Circle Radius Around a Lat/Long Point

Restrict Viewable Area

First create your map as usual; nothing special the creation of the VE map needed. Once you have your code in place to add the map to the page, you just need to handle the maps OnEndPan and OnStartPan events. You do this by attaching event handlers to these events, like the following:

//Attach our onendpan event handler
map.AttachEvent("onendpan", map_onendpan);

//Attach our onstartpan event handler
map.AttachEvent("onstartpan", map_onstartpan);

function map_onendpan(e) { }
function map_onstartpan(e) { }

Next, setup a couple global variables that will be used to define the restriction that will be imposed.

var mapRestrictionDistance = 100;
var mapRestrictionUnit = GeoCodeCalc.EarthRadiusInMiles;

The above two global variables define that you will restrict the map to only be panned within 100 miles of the maps original center point.

Next, you need to add code to the event handler method stubs shown above that will actually restrict the maps viewable area.

In the map_onstartpan event handler you will record the maps center point in a global variable before the panning begins. To do this add the following code:

// global variable to keep track of maps center point before panning began
var mapStartPanPoint = null;

function map_onstartpan(e)
{
    //Get the current map center point before panning begins
    mapStartPanPoint = map.GetCenter();
}

In the map_onendpan event handler you will place the actual code that imposes our restriction. The following code will check if the map has been panned past the desired limitation of 100 miles from the original center point. If it has, it will reposition the map back to the last point the map was at before the invalid panning began. Here's the code to implement this within the map_onendpan event handler:

function map_onendpan(e)
{
    //Get total distance panned from map center
    var distance = GeoCodeCalc.CalcDistance(
        mapOriginalCenterPoint.Latitude,
        mapOriginalCenterPoint.Longitude,
        map.GetCenter().Latitude,
        map.GetCenter().Longitude,
        mapRestrictionUnit
        );

    //Check distance panned from original center point
    if (distance > mapRestrictionDistance)
    {
        //Move map back to the last point that was
        //within the desired restriction radius
        map.SetCenter(mapStartPanPoint);
    }
}

Restrict Maximum Zoom Level

To add the Maximum Zoom Level restriction all you need to do is implement a handler for the maps OnEndZoom event.

Use the following code to attach an event handler to the OnEndZoom event:

//Attach our onendzoom event handler
map.AttachEvent("onendzoom", map_onendzoom);

function map_onendzoom(e) { }

Before you write the code that will place a restriction on the maximum zoom level, you need to declare a global variable that will define what the maximum zoom level will be.

var mapRestrictionZoomLevel = 7;

Now that you have the global variable in place, and the event is being handled by the map_onendzoom method stub, you need to add the following code to the method that will put the zoom level restriction in place:

function map_onendzoom(e)
{
    //Check if the map is zoomed out further than
    //the set restriction
    if (e.zoomLevel < mapRestrictionZoomLevel)
    {
        //Zoom the map back in to the restricted area
        map.SetZoomLevel(mapRestrictionZoomLevel);
    }
}

Conclusion

This is actually some rather simple code to write (at least when utilizing the GeoCodeCalc class) and it provides some good functionality to keep your users from possibly getting lost, along with potentially reducing the number of Virtual Earth Map Transactions you'll end up paying for.

Be the first to rate this post

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

Categories: Virtual Earth
Posted by crpietschmann on Saturday, May 03, 2008 8:36 PM
Permalink | Comments (0) | Post RSSRSS comment feed

Virtualization on the Desktop: VirtualPC 2007 and Hyper-V

About a year ago I started to use VirtualPC 2007 on my Vista x64 box to allow me to run other instances of OS's within isolation without requiring me to purchase anymore hardware for my desk. It's actually rather simple to do and makes it extremely easy to roll back any of your systems to a previous state in case they get screwed up by installing beta software or for any other reason.

Benefits of Virtualization 

To backup a virtual machine, all you do is burn the virtual machines files to a DVD. And, to restore, all you do is copy those backups over the existing files, and things are restored to a previous state. Simple, clean and straight forward.

Also, another benefit to using virtual machines is you only have to install and activate Windows XP or Vista once. Once you've installed and activated, all you need to do to install a new instance is copy the virtual machine files for the "fresh" install from your backup to a folder of their own on your machine and you have a whole new virtual machine to play around with.

How I've been using Virtualization 

One thing that's been lacking in my use of virtualization (using VirtualPC 2007) is the fact that I have still been using the main installation on my machine for my own general purpose (development, testing, some games, etc.) use. And, the only thing I've been using virtualization for, thus far, is for testing out new software or beta software. This is fine and all, but it still puts my machine at risk of getting messed up from the usual install and uninstall of random things, and getting full of alot of software being installed that just plain slows down the machine and such.

What's new in Virtualization?

The latest from Microsoft is Hyper-V for Windows Server 2008. I'm still reading up on exactly what Hyper-V is, and what it's benefit are over Virtual Server 2005 and VirtualPC 2007.

According to Microsoft, Windows Server 2008 Hyper-V is:

"Windows Server 2008 Hyper-V, the next-generation hypervisor-based server virtualization technology, allows you to make the best use of your server hardware investments by consolidating multiple server roles as seperate virtual machines (VMs) running on a single physical machine. With Hyper-V, you can also efficiently run multiple different operating systems -- Windows, Linux and others -- in parallel, on a single server, and fully leverage the power of x64 computing."

Here are some links so you can learn more about Windows Server 2008 Hyper-V:

Windows Server 2008: Virtualization and Server Consolidation
Step-by-Step Guide to Getting Started with Hyper-V
Windows Server 2008 Server Virtualization Webcasts
Microsoft Windows Virtualization Team Blog
Windows Server 2008 Revealed: Hyper-V Virtualization

What I'm looking to do with Virtualization

Lately, I've been thinking about using Windows Server 2008 as the host OS on my main machine and using Vista and XP as guest OS's using virtualization. I'm looking to break out each of the roles I perform into separate virtual machines. So, basically I'm looking to having virtual machines for the following roles:

  • Development - Mainly Visual Studio and SQL Express using Vista
  • Testing - Probably have two virtual machines for this, one Vista and the other XP
  • General Purpose - Mainly Office 2007 and CD/DVD burning software
  • Playground - Use for testing new software and beta/alpha software. Probably have a couple VM's for this, including one with Visual Studio for testing out "found code" and open source code downloaded from internet.
  • Gaming - Install any games I play here

You may be thinking that I could use Virtual Server 2005 to do this, but it doesn't support Vista as the host OS and you can't see Vista's "Aero" Glass while using remote desktop from a non-Vista OS. And, I just plain like the way Vista looks, so that's out of the question.

I can use VirtualPC 2007 with Vista as the host OS to do all this, and everything will be just dandy. However, since we now have Windows Server 2008 and Hyper-V, I might as well look at that as an option.

I'll post an update once I decide what I'm going to do to fill my virtualization needs.
But until then, if you have any virtualization suggestions and/or tips using VirtualPC, Virtual Server or Hyper-V, please post them in the comments.

Be the first to rate this post

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

Categories: General
Posted by crpietschmann on Monday, April 28, 2008 5:11 PM
Permalink | Comments (4) | Post RSSRSS comment feed

Virtual Earth Resources

Here's links to some excellent resources for MS Virtual Earth development:

Virtual Earth Concepts by Mike Garza
These are some excellent concept examples for building rich user experiences with Virtual Earth. Some of the examples include: Draggable Shapes/Pushpins,  Select plotted Shapes using a Selection Box, and Sidebar listing plotted Shapes that highlights the Shape on the map when hovered over. Today he just posted two new examples of adding Drag Handles to Polygons and Polylines to allow the user to easily move/resize the shapes using the Mouse. These are some really excellent example!

ViaVirtualEarth and ViaWindowsLive
Both of these sites are run by the same guys, but both contains some really excellent articles. I don't know if they are still updating ViaVirtualEarth, I believe ViaWindowsLive was created as a replacement.

Virtual Earth Interactive SDK
This is the official interactive SDK for Virtual Earth. I should need to list this since everyone probably already knows about it, but it's such a great resourec I can't leave it out.

Virtual Earth Forums on MSDN
These are the official Microsoft forums for Virtual Earth development

Virtual Earth 3D Team Blog
This is the new blog started by the Virtual Earth 3D Team. It already has a couple nice articles. I hope they keep this one up and keep adding content.

Hannes's Virtual Earth Blog
He has alot of code posted on various topics working with Virtual Earth. Definately a nice resource.

Keith Kinnan's Blog
There is alot of Virtual Earth content posted here. An excellent resource.

And lastly...
You can find a bunch of the articles I've written myself in the Virtual Earth category of my Blog.

If you know of any resources not listed here, please post them in a comment. Happy Mapping!

Be the first to rate this post

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

Categories: Virtual Earth
Posted by crpietschmann on Friday, April 25, 2008 2:52 PM
Permalink | Comments (0) | Post RSSRSS comment feed

Virtual Earth: Center Map to Shape during OnClick Event

Here's a short, simple example of wiring up Virtual Earth to zoom/pan the map to showing the best fit to center on a specific Shape object that is clicked on by the user.

This example works in both 2D and 3D map modes.

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
<head>
<title></title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<script type="text/javascript" src="http://dev.virtualearth.net/mapcontrol/mapcontrol.ashx?v=6.1"></script>
<script type="text/javascript">
var map = null;


function GetMap()
{
    map = new VEMap('myMap');
    map.LoadMap();



    /// Attach a handler to the Maps OnClick Event


    map.AttachEvent("onclick", Map_OnClick);


 


    /// Add a couple Pushpin Shapes to the map


    var shape1 = new VEShape(VEShapeType.Pushpin, new VELatLong(49.74999, -99.71));
    shape1.SetTitle("Shape 1");
    shape1.SetDescription("Test Shape 1");
    map.AddShape(shape1);


    var shape2 = new VEShape(VEShapeType.Pushpin, new VELatLong(39.74999, -96.71));
    shape2.SetTitle("Shape 2");
    shape2.SetDescription("Test Shape2");
    map.AddShape(shape2);


    /// Add a Polygon Shape to the map


    var shape3points = new Array();
    shape3points[shape3points.length] = new VELatLong(37.74999, -99.71);
    shape3points[shape3points.length] = new VELatLong(37.74999, -110.71);
    shape3points[shape3points.length] = new VELatLong(32.74999, -111.71);
    var shape3 = new VEShape(VEShapeType.Polygon, shape3points);
    shape3.HideIcon(); // Hide the Polygons Icon Image
    map.AddShape(shape3);


}


function Map_OnClick(e)
{
    // Check if a Shape was clicked
    if (e.elementID != null)
    {
        // Get a reference to the Shape that was clicked
        var shape = map.GetShapeByID(e.elementID);


        // Set the MapView to the Shapes collection of VELatLong points
        // This will zoom and pan the map to the best view to show all the points of this Shape
        map.SetMapView(shape.GetPoints());
    }
}
</script>
</head>
<body onload="GetMap();">
<div id='myMap' style="position:relative; width:400px; height:400px;"></div>
</body>
</html>

Be the first to rate this post

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

Categories: Virtual Earth
Posted by crpietschmann on Thursday, April 24, 2008 10:02 PM
Permalink | Comments (0) | Post RSSRSS comment feed