I Can't Believe That Worked

Code and Ideas, minus the profanity (the one language all developers know)
Silverlight Bing Maps Control and Drag & Drop

Hello All,

I was recently asked to build up a Silverlight tool to show a file full of addresses on a map. I decided to use the Silverlight bing maps control and I must say I was not disappointed with it's functionality. It ended up being extremely simple. The tools used to create this were VS2010, Silverlight 4, Bing maps Silverlight control, and the Bing maps web services.

Setting up the Bing Maps account:

All you need is a live account and your good to go: https://www.bingmapsportal.com/. Log in with your Live ID and enter your app name and URL and the keys are in the ignition!

Get the Bing Maps Control:

Grab it from: http://www.microsoft.com/downloads/details.aspx?displaylang=en&FamilyID=beb29d27-6f0c-494f-b028-1e0e3187e830. Install that bad boy and create your Silverlight app in VS2010.

Adding the Map Control to your app:

<UserControl x:Class="PeopleMap.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:m="clr-namespace:Microsoft.Maps.MapControl;assembly=Microsoft.Maps.MapControl"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d"
    d:DesignHeight="300" d:DesignWidth="400" AllowDrop="True">
    <Grid x:Name="LayoutRoot" Background="White">
        <m:Map x:Name="myMap" CredentialsProvider="Your Key!!" Mode="Road"/>
    </Grid>
</UserControl>

Make sure to mark the user control from your main view to allow drop. I’m expecting a file with each address on the new line.

 

Add in the reference to the Bing Geocoding services to your Silverlight project:

Add in a Service Reference to your Silverlight project with the following URL: http://dev.virtualearth.net/webservices/v1/geocodeservice/geocodeservice.svc. I used the namespace of “BingGeocode”.

 

Add in code to handle the Geocode / location calls and throw some pins onto your map:

using System;
using System.IO;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using Microsoft.Maps.MapControl;
using PeopleMap.BingGeocode;
 
namespace PeopleMap
{
    public partial class MainPage : UserControl
    {
        public MainPage()
        {
            InitializeComponent();
            Drop += MainPage_Drop;
        }
 
        private void MainPage_Drop(object sender, DragEventArgs e)
        {
            if (e.Data != null)
            {
                var files = e.Data.GetData(DataFormats.FileDrop) as FileInfo[];
                var firstFile = files.IfNotNull(i => i.FirstOrDefault());
                firstFile.IfNotNull(i =>
                                        {
                                            using (var streamReader = firstFile.OpenText())
                                            {
                                                while (!streamReader.EndOfStream)
                                                {
                                                    RequestAddress(streamReader.ReadLine());
                                                }
                                            }
                                        });
            }
        }
 
        private void RequestAddress(string lineText)
        {
            var geocodeRequest = new GeocodeRequest { Query = lineText };
            var geocodeClient = new GeocodeServiceClient();
            geocodeRequest.Credentials = new Credentials
                                             {
                                                 ApplicationId =
                                                     ((ApplicationIdCredentialsProvider) myMap.CredentialsProvider).
                                                     ApplicationId
                                             };
            geocodeClient.GeocodeCompleted += GeocodeClientGeocodeCompleted;
            geocodeClient.GeocodeAsync(geocodeRequest);
        }
 
        private void GeocodeClientGeocodeCompleted(object sender, GeocodeCompletedEventArgs e)
        {
            if(e.Error == null)
            {
                var firstResult = e.Result.Results.FirstOrDefault();
                if (firstResult != null)
                {
                    var location = firstResult.Locations.FirstOrDefault();
                    var pin = new Pushpin {Location = location};
                    pin.SetValue(ToolTipService.ToolTipProperty, new TextBlock{Text = firstResult.DisplayName});
                    myMap.Children.Add(pin);
                }
            }
            else
            {
                throw new Exception(e.Error.Message);
            }
        }
    }
}

 

 

Useful extension methods used:

I end up using these in a bunch of my little projects to do things in line, rather than writing longer code. I think they are more readable. I hope they help you.

using System;
 
namespace PeopleMap
{
    public static class Extenstions
    {
        public static TResult IfNotNull<TArg, TResult>(this TArg obj, Func<TArg, TResult> func) where TArg : class
        {
            return obj != null ? func(obj) : default(TResult);
        }
        
        public static void IfNotNull<TArg>(this TArg obj, Action<TArg> action) where TArg : class
        {
            if (obj != null)
                action(obj);
        }
    }
}

 

My input (just create a txt file with the following addresses on their own lines – if you don’t like Cleveland, insert your own data):

 

50 Public Square, Cleveland, OH
1100 Rock and Roll Blvd., Cleveland, OH
1085 West 3rd Street, Cleveland, OH
1 Center Court, Cleveland, OH

 

That’s about it. The solution was very simple, but very useful. All you have to do, is drop the file on the window, and you have your data show up on the map.

 

Cleveland

 

If you like this, you will probably like the information coming from my twitter account.

Cheers,

David Justice

XAML Default Button

Hey All,

I was working with a client that wanted to have a default button clicked when an enter key is pressed in a textbox (password box to be more specific) within a Silverlight or WPF application. I didn't think much of it. I'll just listen to the event, bind to the button, and click the button on the enter key event. The listening and binding portion is not very tough with an attached property and a little Silverlight 3 element to element binding love. The tricky part came in when I wanted to cause the button click event to be raised. I ended up having to take a page from Josh Smith http://joshsmithonwpf.wordpress.com/2007/03/09/how-to-programmatically-click-a-button/. Thank you, Josh! This may not be the best way to do this, but it works for me.

 

Here is a simple page showing the usage of the default button attached property:

    1 <UserControl x:Class="DefaultButton.MainPage"

    2             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

    3             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

    4             xmlns:d="http://schemas.microsoft.com/expression/blend/2008"

    5             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"

    6             xmlns:DefaultButton="clr-namespace:DefaultButton"

    7             mc:Ignorable="d"

    8             d:DesignWidth="640"

    9             d:DesignHeight="480">

   10     <StackPanel x:Name="LayoutRoot">

   11         <TextBox Text="Press Enter"

   12                 DefaultButton:DefaultButtonService.DefaultButton="{Binding ElementName=button}"

   13                 Width="200" Height="30"/>

   14         <Button x:Name="button" Content="waiting for click..."

   15                Click="Button_Click" Width="200" Height="200"/>

   16         <Button x:Name="reset" Content="Reset" Click="reset_Click" Width="200"/>

   17     </StackPanel>

   18 </UserControl>

 

Here is the code behind that page:

    1 #region Namespaces

    2 

    3 using System.Windows;

    4 using System.Windows.Controls;

    5 

    6 #endregion

    7 

    8 namespace DefaultButton

    9 {

   10     public partial class MainPage : UserControl

   11     {

   12         public MainPage()

   13         {

   14             InitializeComponent();

   15         }

   16 

   17         private void Button_Click(object sender, RoutedEventArgs e)

   18         {

   19             button.Content = "I was Clicked!";

   20         }

   21 

   22         private void reset_Click(object sender, RoutedEventArgs e)

   23         {

   24             button.Content = "waiting for click...";

   25         }

   26     }

   27 }

 

Here is the attached property:

    1 #region Namespaces

    2 

    3 using System.Windows;

    4 using System.Windows.Automation.Peers;

    5 using System.Windows.Automation.Provider;

    6 using System.Windows.Controls;

    7 using System.Windows.Input;

    8 

    9 #endregion

   10 

   11 namespace DefaultButton

   12 {

   13     public static class DefaultButtonService

   14     {

   15         public static DependencyProperty DefaultButtonProperty =

   16             DependencyProperty.RegisterAttached("DefaultButton",

   17                                                 typeof (Button),

   18                                                 typeof (DefaultButtonService),

   19                                                 new PropertyMetadata(null, DefaultButtonChanged));

   20 

   21         private static void DefaultButtonChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)

   22         {

   23             var uiElement = d as UIElement;

   24             var button = e.NewValue as Button;

   25             if (uiElement != null && button != null)

   26             {

   27                 uiElement.KeyUp += (sender, arg) =>

   28                                        {

   29                                            if (arg.Key == Key.Enter)

   30                                            {

   31                                                var peer = new ButtonAutomationPeer(button);

   32                                                var invokeProv =

   33                                                    peer.GetPattern(PatternInterface.Invoke) as IInvokeProvider;

   34                                                if (invokeProv != null)

   35                                                    invokeProv.Invoke();

   36                                            }

   37                                        };

   38             }

   39         }

   40 

   41         public static void SetDefaultButton(UIElement obj, Button button)

   42         {

   43             obj.SetValue(DefaultButtonProperty, button);

   44         }

   45 

   46         public static void GetDefaultButton(UIElement obj)

   47         {

   48             obj.GetValue(DefaultButtonProperty);

   49         }

   50     }

   51 }

All in all, pretty straight forward. 

Cheers,

David

 

UPDATE: I didn't see this, but it looks like Patrick Cauldwell has blogged about a very similar topic in May (in fact the only major thing that separates the code is the binding). You can see his post here: http://www.cauldwell.net/patrick/blog/ALdquodefaultButtonrdquoInSilverlight.aspx.

Genetic Algorithm -- Add Ur Own Func :)

Hi again,

I was a little bored this weekend and needed to add in some GA functionality to a side project. I felt like it would be best to create a simple executer to deal with the iterative behavior of a genetic algorithm. The executer take in funcs provided by the consumer and executes based on a simple iterative model.

I've included a zip of the solution with an example of usage within the accompanying test project.

Below is what I came up with. Cheers!

Code:

    8 #region Dependencies

    9 

   10 using System;

   11 using System.Collections.Generic;

   12 using System.Diagnostics;

   13 using System.Linq;

   14 

   15 #endregion

   16 

   17 namespace GA

   18 {

   19     /// <summary>

   20     /// GeneticAlgorithm runs a genetic algorithm based on an initial population, fitness func, crossover func,

   21     /// optional mutation function, and tollerance

   22     /// </summary>

   23     /// <typeparam name="T">Type to perform the algorithm against</typeparam>

   24     public class GeneticAlgorithm<T>

   25     {

   26         private readonly Func<IEnumerable<FitnessComposite<T>>, IEnumerable<T>> _crossoverFunction;

   27         private readonly Func<IEnumerable<T>, IEnumerable<FitnessComposite<T>>> _fitnessFunction;

   28         private readonly Func<IEnumerable<T>, IEnumerable<T>> _mutationFunction;

   29         private readonly double _tollerance;

   30         private IEnumerable<T> _population;

   31 

   32         /// <summary>

   33         ///

   34         /// </summary>

   35         /// <param name="population">initial population</param>

   36         /// <param name="fitnessFunction">function for calculating fitness</param>

   37         /// <param name="crossoverFunction">breeding fuction</param>

   38         /// <param name="mutationFunction">mutation function (optional, use null if not needed)</param>

   39         /// <param name="tollerance">fitness tollernance</param>

   40         public GeneticAlgorithm(IEnumerable<T> population,

   41                                 Func<IEnumerable<T>, IEnumerable<FitnessComposite<T>>> fitnessFunction,

   42                                 Func<IEnumerable<FitnessComposite<T>>, IEnumerable<T>> crossoverFunction,

   43                                 Func<IEnumerable<T>, IEnumerable<T>> mutationFunction,

   44                                 double tollerance)

   45         {

   46             _population = population;

   47             _fitnessFunction = fitnessFunction;

   48             _crossoverFunction = crossoverFunction;

   49             _mutationFunction = mutationFunction;

   50             _tollerance = tollerance;

   51         }

   52 

   53         /// <summary>

   54         /// Max number of results to return

   55         /// </summary>

   56         public int? MaxResults { get; set; }

   57 

   58         /// <summary>

   59         /// Max time the algorithm can run

   60         /// </summary>

   61         public TimeSpan? TimeOut { get; set; }

   62 

   63         /// <summary>

   64         /// Result of the algorithm

   65         /// </summary>

   66         public IEnumerable<FitnessComposite<T>> Results { get; private set; }

   67 

   68         /// <summary>

   69         /// Number of generations

   70         /// </summary>

   71         public int Generations { get; private set; }

   72 

   73         /// <summary>

   74         /// Has the algorithm reach the finish criteria (either time has expired, or the tollerance has been reached)

   75         /// </summary>

   76         public bool IsDone { get; private set; }

   77 

   78         /// <summary>

   79         /// The evolving population

   80         /// </summary>

   81         public IEnumerable<T> Population

   82         {

   83             get { return _population; }

   84         }

   85 

   86         /// <summary>

   87         /// Run the algorithm until complete and perform the doneAction at completion

   88         /// </summary>

   89         /// <param name="doneAction">action to be performed when the algorithm time has expired or tollerance has been reached</param>

   90         public void Run(Action<IEnumerable<FitnessComposite<T>>> doneAction)

   91         {

   92             var executer = new Executer(_population)

   93                                {

   94                                    BreedingFunc = GetBreedingFunc(),

   95                                    FitnessFunc = _fitnessFunction,

   96                                };

   97 

   98             if (TimeOut.HasValue)

   99             {

  100                 var timer = new Stopwatch();

  101                 timer.Start();

  102                 executer.FinishCriteria = fitnessItems => IsFitnessReached(fitnessItems) || timer.Elapsed > TimeOut;

  103                 InternalRun(executer, doneAction);

  104                 timer.Stop();

  105             }

  106             else

  107             {

  108                 executer.FinishCriteria = IsFitnessReached;

  109                 InternalRun(executer, doneAction);

  110             }

  111         }

  112 

  113         private void InternalRun(Executer executer, Action<IEnumerable<FitnessComposite<T>>> doneAction)

  114         {

  115             while (executer.Run())

  116             {

  117                 _population = executer.Population;

  118                 Generations++;

  119             }

  120 

  121             IsDone = executer.IsDone;

  122             Results = executer.Results.Where(FitnessIsLessThanOrEqualToTollerance);

  123             if (MaxResults.HasValue && Results.Count() > MaxResults.Value)

  124                 Results = Results.Take(MaxResults.Value);

  125 

  126             doneAction(Results);

  127         }

  128 

  129         private Func<IEnumerable<FitnessComposite<T>>, IEnumerable<T>> GetBreedingFunc()

  130         {

  131             return _mutationFunction != null

  132                        ? i => _mutationFunction(_crossoverFunction(i))

  133                        : _crossoverFunction;

  134         }

  135 

  136         private bool IsFitnessReached(IEnumerable<FitnessComposite<T>> fitnessComposites)

  137         {

  138             return FitnessIsLessThanOrEqualToTollerance(GetBestFitness(fitnessComposites));

  139         }

  140 

  141         private FitnessComposite<T> GetBestFitness(IEnumerable<FitnessComposite<T>> fitnessComposites)

  142         {

  143             return fitnessComposites.OrderBy(i => i.Fitness).First();

  144         }

  145 

  146         private bool FitnessIsLessThanOrEqualToTollerance(FitnessComposite<T> ratedObject)

  147         {

  148             return ratedObject.Fitness <= _tollerance;

  149         }

  150 

  151         #region Nested type: Executer

  152 

  153         private class Executer

  154         {

  155             private IEnumerable<T> _internalPopulation;

  156 

  157             public Executer(IEnumerable<T> initialPopulation)

  158             {

  159                 _internalPopulation = initialPopulation;

  160             }

  161 

  162             public bool IsDone { get; private set; }

  163             public Func<IEnumerable<FitnessComposite<T>>, bool> FinishCriteria { get; set; }

  164             public Func<IEnumerable<T>, IEnumerable<FitnessComposite<T>>> FitnessFunc { get; set; }

  165             public Func<IEnumerable<FitnessComposite<T>>, IEnumerable<T>> BreedingFunc { get; set; }

  166             public IEnumerable<T> Population { get; private set; }

  167             public IEnumerable<FitnessComposite<T>> Results { get; private set; }

  168 

  169             public bool Run()

  170             {

  171                 var fitnessComposites = FitnessFunc(_internalPopulation);

  172                 IsDone = FinishCriteria(fitnessComposites);

  173                 if (!IsDone)

  174                     _internalPopulation = BreedingFunc(fitnessComposites);

  175                 else

  176                     Results = fitnessComposites;

  177                 Population = _internalPopulation;

  178                 return !IsDone;

  179             }

  180         }

  181 

  182         #endregion

  183     }

  184 }

Twitter: David Justice

Download the Code

.Net 4.0 Reflection vs. Dynamics vs. Property Setting With Times

 

Hello All,

 

Today I found my self hanging out after a sprint review with my partner in crime Kevin Rohling.  TFS was down (not tfs's fault, but some other freak accident...) and I hadn't installed VS 2010 yet, so it seemed like the perfect time to do such things. I got everything up and running, and Kevin and I got into a discussion about Dynamics & performance. We made a quick lunch bet on which is faster, reflection or dynamics for simply setting a property. I figured reflection would be quicker, while Kevin thought dynamics would be faster. Well, I owe him lunch now. The code is below.

 

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

 

namespace ConsoleApplication1

{

    class Program

    {

        static void Main(string[] args)

        {

            var nTimes = 1000000;

            var value = "Hello World";

            var myTestType = new MyTestType();

            DateTime start, end;

            var property = typeof(MyTestType).GetProperty("MyDynamicProperty");

 

            start = DateTime.Now;

            for (var i = 0; i < nTimes; i++)

            {

                //var property = typeof(MyTestType).GetProperty("MyDynamicProperty");

                property.SetValue(myTestType, value, null);

            }

            end = DateTime.Now;

            Console.WriteLine(end.Subtract(start).ToString());

 

            dynamic myTestType2 = new MyTestType();

            start = DateTime.Now;

            for (int i = 0; i < nTimes; i++)

            {

                myTestType2.MyDynamicProperty = value;

            }

            end = DateTime.Now;

            Console.WriteLine(end.Subtract(start).ToString());

 

            var myTestType3 = new MyTestType();

            start = DateTime.Now;

            for (int i = 0; i < nTimes; i++)

            {

                myTestType3.MyDynamicProperty = value;

            }

            end = DateTime.Now;

            Console.WriteLine(end.Subtract(start).ToString());

 

            Console.ReadLine();

        }

 

        public class MyTestType

        {

            public string MyDynamicProperty { get; set; }

        }

    }

}

 

Results:

Reflection: 00:00:19.8581040

Dynamics: 00:00:00.6054300

Setting a property plain and simple: 00:00:00.0166005

 

Kevin was right by a long shot!! Who would have guessed that dynamics would be so fast. I'm quite impressed, and tip my hat to the guys that cooked that up! Cheers fellas, but thanks a lot for making my buy lunch...

 

On a side note: Congrats to Kevin Rohling on his winning new CloudApp() with his submission of www.myimpulselive.com!  Check out the app. It's pretty darn slick!

 

Silverlight Facebook Client Side API v0.001

Hello All!

Lately, I have been spending some time working with Silverlight in the context of the Facebook api.  I've been amazed at the amount of data the api gives you access to.  With the incredible growth facebook is experiencing (check this out: http://www.insidefacebook.com/2008/07/29/tracking-facebooks-2008-international-growth-by-country/), there are many opportunities blooming for developers that can use the information to improve / innovate with their own products.  If you are a marketing / advertising business and you are not leveraging this information in one way or another, then I would say you are missing out!

In a past post (Facebook Connect Post) I showed everyone how to set up an application in Facebook and how to use Facebook Connect with Silverlight to create a simple login screen.  That was a trivial proof of concept to show how one might implement such things on their Silverlight App.  This post will build on the previous post, and introduce a very alpha version of a Silverlight client side api I have been working on for a little bit.  

There has been many articles written on how to hook up the a Silverlight app to Facebook, but it's always used the web server as a bridge to get the data back from the Facebook api.  Pete Brown did a wonderful job illustrating this in this blog post using the Facebook Developer Toolkit via Clarity Consulting.  I think using your web server as the bridge to the Facebook api is slightly wasteful.  As a result of that conclusion I decided to port the api to the client side.  I felt it would be nice to offload much of the weight of the web requests onto the Facebook servers rather than my poorly funded web servers :).  I also think this will allow for an architecture that will scale much better than the web server bridge.

<disclaimer>

If / When you look at the code, please understand this is just an api and a demo.  There is little or no abstraction.  There is no caching / real object model.  I built this as a proof of concept and will advance it in a bit.  Heck, I don't even know if this is going to garner any attention...

</disclaimer>

When I was building the api, I came to the conclusion, very early down the path, that web request completed event handlers and custom delegates are the devil, Bobby Boucher.  I always want to write the call to the method, then have to go back and wire up the delegate for the call back.  It bugs the hell out of me that I can't just pass an action into the method call.  With that thought in my head, I made the api use generic actions passed into the api requests rather than callbacks.  I'm not sure how this will go over, but I have found it a little easier to read.  I do love lambdas, so I might be a bit biased in that choice.

One important thing to note about the Facebook api:  It might not give you back what the xsd promises.  I think I have fixed all of the places where this issue cropped up.

After you download the code, there are few things you will need to do to run the demo app.  You will need to follow my original post to create an application in Facebook and get facebook connect set up for the demo.  Basically, after you get your application key and secret key, you just need to plug them into a couple spots (ApplicationContext.cs, Default.aspx, and your secret key in value for app setting "secret" in the web.config).  You may also need to update your service references to point to the fake host name you set up in your hosts file (from the previous post).  That should get you to the point where you have the demo running.

Comments are welcomed.  Bugs are welcomed.  Calling me a complete butthead is welcomed.  I will get back to you if you are kind enough to ask about something.

Finally, I have to give a couple shout outs.  Thank you very much to the Madison, WI .NET Users group for letting me use your members as a sounding board.  Lance Larsen and Travis Feirtag were kind enough to give me some time at the latest meeting.  Thank you very much guys.  Check them out at http://www.maddotnet.com/.  Last but not least, I want to give a big high five to the guys over at http://mightymeaty.members.winisp.net/blacklight.silverlight/.  They do some really cool stuff with Silverlight controls.  I'm continually impressed with the quality and UX this group creates.  If you look at the controls in the demo, you will notice i'm utilizing some of their controls and styles.  I would recommend testing out their stuff if you get a chance.

Twitter: David Justice

Code

kick it on DotNetKicks.com

Azure 1/10 + Facebook Connect 1/2 + Silverlight 2/5 = Fun

Hello all!  First off, I want to say this post does not reflect the way I think authentication should be handled.  I don't necessarily agree with the route Facebook has decided to go with Connect, but that is a debate I don't really wish to be a part of right now.  I would like to concentrate on the superlatives about Facebook Connect and the possibilities this opens up to developers.  If you wish to discuss the positives and negatives of the Facebook Connect strategy, please be my guest to comment till your angelic heart is content.

In this post, I'm going to set up an Azure cloud service project with a single web role that hosts a Silverlight 2 page, which utilizes Facebook Connect.  I will not go into other portions of the Facebook API during this post, but I will extend it in a later post.  Basically this is 1/10 an excersize in creating a cloud service, 1/2 using Facebook connect, and about 2/5 interactions between JavaScript and Silverlight.  Ok, let's get started.

Things needed:

1)      Azure CTP

2)      Silverlight 2

3)      Facebook account

 

Let first open Visual Studio 2008 and create an Web Cloud Service and call it AzureFaceBookConnect.

After that is created, let's add our Silverlight Application.  We'll call it FaceBookConnect (common theme, huh).

Next let's go set up our developer account with Facebook.  For this step you will need a Facebook login.  It's not that bad...  Plus you might actually like it if you haven't been sucked into the blackhole that is Facebook :).  Go to Facebook Developers.

Click on the "Set Up New Application" button.  We are going to create an application called {Test Connect} <--- just put whatever you want.  Just like code, if you keep your misspellings all the same, then the compiler still loves you :).

So, just agree to everything, and use the old settings editor.  You can use the updated settings editor, but the old settings editor has everything we need.  Plus, the old settings editor doesn't have as many shinny buttons!  In the editor, you should see something like below.

Please make sure to fabricate a good domain name.  We will be using it in the near future.  Actually, this doesn't need to be a real domain as you can see from mine above.  We are going to update our host file, so we can test without having to use a real domain.  This can be pretty useful!  You can probably find your host file on a windows machine at C:\Windows\System32\drivers\etc.  Also, take note of the Callback URL.  The callback url will be used by the Facebook client js for authentication, and needs to be of the same base domain.

We will need to create two pages.  One to host our client page, and another page to host the callback js for Facebook.  You can't tell from above, but I named the callback page FbConnectCallback.aspx.

I love the old faithful, notepad!  You can see above, I've added the fake domain, and mapped back to localhost.  You will need to specify this domain when you are running your code.  Facebook needs to call back to a page which it thinks originates from the base domain.  We just want to spoof the domain.

Now onto some code:  Default.aspx

<%@ Register Assembly="System.Web.Silverlight" Namespace="System.Web.UI.SilverlightControls"

    TagPrefix="asp" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">

<head id="Head1" runat="server">

    <title>FaceBookConnect</title>

</head>

<body style="height: 100%; margin: 0;">

    <form id="form1" runat="server" style="height: 100%;">

    <asp:ScriptManager ID="ScriptManager1" runat="server" />

    <div style="height: 100%;">

        <asp:Silverlight ID="Xaml1" runat="server" Source="~/ClientBin/FaceBookConnect.xap"

            MinimumVersion="2.0.31005.0" Width="100%" Height="100%" />

 

        <script src="http://static.ak.connect.facebook.com/js/api_lib/v0.4/FeatureLoader.js.php"

            type="text/javascript"></script>

 

        <script type="text/javascript">

            FB.init("{You're API Key from setting up you developer account}", "/FbConnectCallback.aspx");

            function facebook_onlogin() {

                var slcontrol = $get('Xaml1');

                slcontrol.Content.slPage.LoggedIn();

            }

            function login() {

                FB.Connect.requireSession(facebook_onlogin);

            }

            function logout() {

                FB.Connect.logout();

            }

        </script>

 

    </div>

    </form>

</body>

</html>

 

Please pay close attention to the Facebook FeatureLoader script tag, and the fact it is placed in the body.  That is manditory for the js to function properly.

 

Next Up: FbConnectCallback.aspx

 

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="FbConnectCallback.aspx.cs" Inherits="AzureFaceBookConnect_WebRole.FbConnectCallback" %>

 

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

 

<html xmlns="http://www.w3.org/1999/xhtml" >

<head runat="server">

    <title>FbConnectCallback</title>

</head>

<body>

<script src="http://static.ak.connect.facebook.com/js/api_lib/v0.4/XdCommReceiver.js" type="text/javascript"></script>

</body>

</html>

 

Again, pay attention to where the script tag is placed.

 

Now for the Silverlight: Page.xaml

 

<UserControl x:Class="FaceBookConnect.Page"

   xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

   xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">

    <Canvas>

        <Button x:Name="btnLogin" Click="Button_Click">

            <Button.Content>

                <Image Source="Images/connect_light_medium_long.png"/>

            </Button.Content>

        </Button>

    </Canvas>

</UserControl>

 

This page is just going to host a login / logout button.  You may say, that is not very useful.  I would agree with you, but I can imagine this could be useful for some other cases that are not quite a simple as this one...

 

CodeBehind: Page.xaml.cs

 

#region

 

using System;

using System.Windows;

using System.Windows.Browser;

using System.Windows.Controls;

using System.Windows.Media.Imaging;

 

#endregion

 

namespace FaceBookConnect

{

    [ScriptableType]

    public partial class Page : UserControl

    {

        private bool _loggedin;

 

        public Page()

        {

            this.InitializeComponent();

            this.Loaded += this.Page_Loaded;

        }

 

        private void Page_Loaded(object sender, RoutedEventArgs e)

        {

            HtmlPage.RegisterScriptableObject("slPage", this);

        }

 

        [ScriptableMember]

        public void LoggedIn()

        {

            this.btnLogin.Content = new Image

                 {

                    Source = new BitmapImage(

                    new Uri("Images/logout_large.png",

                             UriKind.Relative))

                 };

            this._loggedin = true;

        }

 

        private void Button_Click(object sender, RoutedEventArgs e)

        {

            if (this._loggedin == false)

            {

                HtmlPage.Window.Invoke("login");

            }

            else

            {

                HtmlPage.Window.Invoke("logout");

                this.btnLogin.Content = new Image

                    {

                       Source = new BitmapImage(

                       new Uri("Images/connect_light_medium_long.png",

                                UriKind.Relative))

                    };

                this._loggedin = false;

            }

        }

    }

}

 

What are we doing here?  Basically, this code invokes login, and logout in js in the page.  On login confirmed from facebook, we are alerted via script calling into managed code.  I didn't bother styling the button very much...  It's pretty lame as far as that goes, but it does achive the end goal -- bring in the designers :)!

 

Now what should our project look like...  I'm going over this pretty quick, because the code will be zipped up down below.  I will give you the opportunity to go over it yourself :).

 

That's pretty much it. Please check out the code below.  As always, thank you.. come again!

 

Twitter: @DavidJustice

 

Code

 

kick it on DotNetKicks.com

Silverlight 2 XAML Binding and Custom / Core Dependency Properties

Lately, I have been working in Silverlight 2 quite a bit.  I have been infused with inspiration from the Chicago PhizzPop Design Challenge.  I'm waiting for the pictures and vids from a couple people to be served.  I will be linking them into the blog.  For the time being, I have been hacking away at some of my own interests.

I ran into some interesting issues with the SL 2 binding.  I don't think these are new.  There have been several posts about them in the past, but I wanted to dig into them for myself, and see what reflector had to say about it.

Update:  I was completely wrong... "I will take SWORDS for 500 Alex"

Thankfully, a very friendly and knowledgeable Justin-Josef Angel helped me out with the issue and learned me 'bout some silverlight.  Thank you very much Justin!  Ok, so what I was trying to do was a little boneheaded  (we all know pride tastes really bad)...  Really, the way around the issue, as Justin pointed out, is to handle the PropertyChangedCallback on the dependency property rather than trying to place logic in the setter of the CLR Property which fronts the DependencyProperty.  I am providing below the updated GlassButton class with the changes suggested.

We can all be pretty damn dumb from time to time.  All we can hope is to try to learn from our mistakes, so we can be just that little bit better the next day.  Anything you read below with a line struck through it, is null and void (aka dumbness).  I hope this helps everyone out :).

public class GlassButton : Button

    {

        public static readonly DependencyProperty _radiusProperty = DependencyProperty.Register("Radius",

                                                                                                typeof (double),

                                                                                                typeof (GlassButton),

                                                                                                new PropertyMetadata(

                                                                                                    new PropertyChangedCallback

                                                                                                        (RadiusCallback)));

 

 

        public double Radius

        {

            get { return (double) this.GetValue(_radiusProperty); }

            set { this.SetValue(_radiusProperty, value); }

        }

 

        private static void RadiusCallback(DependencyObject d, DependencyPropertyChangedEventArgs e)

        {

            var value = (double) e.NewValue;

            if (value > 0)

            {

                ((FrameworkElement) d).RenderTransform = new ScaleTransform {ScaleX = value/26, ScaleY = value/26};

            }

        }

    }

 

The basic scenario is as follows:  I have done quite a bit of WPF programming in the past (since back when it was WinFx).  I feel pretty damn good about the bindings in WPF, and I feel like I have wrapped my head around binding and dependency properties pretty well.  So, I thought when I decided to write Silverlight 2 apps rather than WPF apps, it would be a very similar feeling.  The feeling was abruptly interrupted by the evilness of the ElementName Binding param.  For those of you who have spent time writing WPF apps, you will know the joy of binding element properties to each other and having no problems.  It's easy to take such things for granted.

I understand you have to trim down the size of the download package for SL, and I am perfectly groovy with that fact.  The issue I have with it, is that there is no recourse for a developer to step outside of those bounds.  Meaning, I would like to have my CustomDependencyProperties be able to take part in XAML binding, the same way CoreDependencyProperties take part in binding.  Below, I'm going to outline some code to illustrate my issue.  Mind you this code is not at all cool.  It just is there to elucidate my point.  If you want cool code, you can look to my boy Brownie, or some other person in a better mood.

XAML:

<UserControl x:Class="Test.Page"

   xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

   xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

   xmlns:Test="clr-namespace:Test"

   Width="400" Height="300">

    <Canvas>

        <Canvas.Resources>

            <Test:BindingHelper x:Key="bindingHelper"/>

        </Canvas.Resources>

        <Test:GlassButton x:Name="glass" Content="{Binding Value, Source={StaticResource bindingHelper}}"

                         Radius="{Binding Value, Source={StaticResource bindingHelper}}" Canvas.Top="10"/>

        <Slider Value="{Binding Value, Source={StaticResource bindingHelper}, Mode=TwoWay}"

               Width="100" Maximum="100" Minimum="0" Height="20"/>

    </Canvas>

</UserControl>

BindingHelper:

#region

 

using System.ComponentModel;

 

#endregion

 

namespace Test

{

    public class BindingHelper : INotifyPropertyChanged

    {

        private double value;

 

        public double Value

        {

            get { return this.value; }

            set

            {

                this.value = value;

                if (this.PropertyChanged != null)

                {

                    this.PropertyChanged(this, new PropertyChangedEventArgs("Value"));

                }

            }

        }

 

        #region INotifyPropertyChanged Members

 

        public event PropertyChangedEventHandler PropertyChanged;

 

        #endregion

    }

}

GlassButton:

#region

 

using System.Windows;

using System.Windows.Controls;

using System.Windows.Media;

 

#endregion

 

namespace Test

{

    public class GlassButton : Button

    {

        public static readonly DependencyProperty _radiusProperty = DependencyProperty.Register("Radius", typeof (double),

                                                                                  typeof (GlassButton), null);

 

 

        public double Radius

        {

            get { return (double)GetValue(_radiusProperty); }

            set

            {

                if (value > 0)

                {

                    this.RenderTransform = new ScaleTransform {ScaleX = value/26, ScaleY = value/26};

                    this.SetValue(_radiusProperty, value);

                }

            }

        }

    }

}

Check out the code if you will.  It's in a nice little sln zipped up, with a bow on top.  Cheers!  CODE ZIPPED UP

Twitter: @DavidJustice

kick it on DotNetKicks.com

Silver Lining for Windows Azure -- Silverlight 2 Sample Hosted in Azure

OK, so I'm starting to sound repetitive about my excitement around Windows Azure, but I really think it will help developers create new products with an all time low cost to enter their specific market.   Not only will it cost less to enter into their market, I think it will help them scale their service offerings as their business grows.  We all want our businesses to grow, but many of the initial development choices one makes when driving to release a product do not always make sense when your customer base grows in a few orders of magnitude.

I'm also stoked about the Silverlight Toolkit released 10.29.2008 (haven't used stoked in a while - I wonder if I can bring it back...).  These controls make developing for Silverlight a real joy.  I was skeptical about the Silverlight 1 release, as well as the initial release of WPF (which is like forever ago), not because of the architecture or technology, but because of the lack of controls.  In the case of WPF, many of my fellow developers refused to move from Windows Forms, because of the rich tool sets they already had.  I think MS heard the call and has worked to remedy the situation.

I melded an Azure Web Role project and the Silverlight Toolkit sample to give you guys a quick download, so you can play with them together.  I hope you like it, and I hope it helps you explore some of the new technology.  I call it SilverLining.

You'll need the Azure SDK, and Silverlight tools.

Twitter: @DavidJustice

Unique Identifier Flat File Import with SSIS

This morning I found myself wrestling with SSIS to convert a string from a flat file to a unique identifier via a Data Flow inside of an SSIS package.  I figured this would be a rather trivial case (the midget was kicking my ass!).  I use guids all over for application development and for database keys.  They are very useful, and very dependable.  Here is a line from my flat file:

61898d4c-3a1b-4736-9a36-eb90a23322e0|:|10/13/2008 11:59:58 PM|:|74afebfe-9523-4977-b5f6-5154b6c91211

Anyone see anything wrong with this?  I didn't see anything wrong, outside of the silly |:| delimiter (I don't want to get started on that <rant/> <--- rant with no content!). 

So moving forward, I created a Flat File Source, pointed to the file, had it guess the appropriate type for import (it selected a 36 character dt_str - fine with me), and then went into the advanced edit section and changed the output for the column to be a unique identifier.  I would expect the conversation to take place in the middle somewhere, and if the powers that be smile kindly upon me, all should work out well.  Unfortunately, I would get an error about truncating data, "The value could not be converted because of a potential loss of data."  I was very confused by this.  I tried to push the string input from the flat file data through a Data Converter step and do the conversion there, but that had the same results.  Basically from that point on for about an hour, I tried every different way I could think of to convert that guid string into a SQL unique identifier.

Eventually I gave up.  The web turned up little help, and I was nearing my wits end.  I don't enjoy working on SSIS packages, and this was not helping.  Thankfully, I have an in-house SQL ROCKSTAR!!  My good friend Chuck (a SQL MVP) has helped me though all sorts of SQL issues in the past.  I asked him about this issue, and although he wasn't completely sure, he thought the error might be because I didn't wrap the guid strings in braces.  <rant> I thought he was absolutely insane!  Why the heck would SSIS expect those guids to be in braces!?  Why couldn't it cast them as unique identifiers?  I can say ‘61898d4c-3a1b-4736-9a36-eb90a23322e0' as uniqueidentifier, and the T-SQL world doesn't come to a grinding halt!! </rant>

The new input looks like this:

{61898d4c-3a1b-4736-9a36-eb90a23322e0}|:|10/13/2008 11:59:58 PM|:|{74afebfe-9523-4977-b5f6-5154b6c91211}

I went through the steps above, and tested the solution.  That's it!  It works like a champ now.  Thx u Chuck!!

Twitter: @DavidJustice

 

MetaTable Expression Builder for Fetching Any Object Via Collection of Primary Keys

Basically, I wanted to build a method that gets an object from a data context whatever the primary key may look like, and whatever type that object may be.  I wrote this code a little while ago when I was exploring the DynamicData libs.  I was checking out some of the code in the libs, and noticed a very slick way one of devs was building expressions to grab back a data item based on a single key ID.  I thought the idea of building up the expression completely ROCKED, but I wanted to expand it out to include composite primary keys.  Below is my implementation of the composite primary key object fetcher.  Hopefully, it will make your life a little easier.

 

(Needed to grab the MetaModel class)

 

using System.Web.DynamicData;

 

 

(Create a new MetaModel for your Context or Contexts -- make sure they are only registered once!!  This can be an issue if you put this code in a static constructor, and you happen to have a generic class.  That would cause the code to get executed each time you specify a new generic argument for type construction (sry, I digress))

 

Model = new MetaModel();

Model.RegisterContext(typeof([Your Context Type]));

 

 

(Get your meta table based on the type from your registered context -- need the metadata about the table to figure out the keys)

 

protected static MetaTable GetMetaTable<T>()

{

    return dataModelMetaModel.GetTable(typeof (T));

}


(This is where the heavy lifting occurs.  I commented what is going on.  There is not much more to say.  Enjoy!)

 

private static T FetchObject<T>(MetaTable metatable, IDictionary<string, object> pks)

    where T : class

{

    IQueryable query = metatable.GetQuery();

 

    //build linq expression tree for where clause

    ParameterExpression entityparam = Expression.Parameter(metatable.EntityType, "e");

    List<Expression> internalExpressons = new List<Expression>();

    Expression equalexpression;

    foreach (MetaColumn member in metatable.PrimaryKeyColumns)

    {

        //convert primary key to proper type

        PropertyInfo columnpropertyinfo = member.EntityTypeProperty;

        MemberExpression columnexpresson = Expression.MakeMemberAccess(entityparam, columnpropertyinfo);

        internalExpressons.Add(Expression.Equal(columnexpresson, Expression.Constant(pks[member.Name])));

    }

 

    // build up the primary key expressions

    if (internalExpressons.Count > 1)

    {

        equalexpression = Expression.And(internalExpressons[0], internalExpressons[1]);

        for (int i = 2; i < internalExpressons.Count; i++)

        {

            equalexpression = Expression.And(equalexpression, internalExpressons);

        }

    }

    else

    {

        equalexpression = internalExpressons[0];

    }

 

    // Create the where clause

    LambdaExpression wherelambda = Expression.Lambda(equalexpression, entityparam);

    MethodCallExpression wherecall = Expression.Call(typeof (Queryable), "Where", new[] {metatable.EntityType},

                                                     query.Expression, wherelambda);

    query = query.Provider.CreateQuery(wherecall);

 

    // Call FirstOrDefault to make sure the connection is closed when finished

    // saw some connections staying open when just grabbing the first object.

    return query.Cast<T>().FirstOrDefault();

}

 

Twitter: @DavidJustice

Windows Azure and _NOT_ SQLExpress

I've been very excited recently by the release of Windows Azure, and rest of the Microsoft suite of cloud based services.  I downloaded all of the sdk's, signed up for all the invitation tokens I could, and began writing code.  The Visual Studio templates for Windows Azure projects makes getting your first Azure project up and running super simple.  I did run into one issues with the project templates setting up my first project.

Basically, the DevelopmentStorage.exe.config for windows Azure expects you to have SQLExpress installed on your machine.  I know it probably says it in quite a few places in the documentation, but instructions and documentation are for after the first faliure ;).  I don't have SQLExpress installed on my machine.  I run SQL2008 Dev...  Now, it would not be very tough to go out and download SQLExpress, but I don't want to (a bit of laziness is good for all developers, without it your code would never be DRY).  So, I just went into the DevelopmentStorage.exe.config, and editted the refs for SQLExpress, and just replaced it with localhost (I have an unnamed instance), and all was well in the world of Azure DB Objects.  You should be able to find your DevelopmentStorage.exe.config at C:\Program Files\Windows Azure SDK\v1.0\bin.

I hope you have clear blue skys ahead of you!

UPDATE: I noticed that my development storage was not starting the table service for me.  I reflected out the developmentstorage.exe and found that I was not supplying a proper dbName in the configuration file.  I doctored up my DevelopmentStorage.exe.config configuration file to look like this:

 

<service name="Table" url="http://127.0.0.1:10002/" dbServer="localhost" dbName="developmentstoragedb"/>

 

Twitter: @DavidJustice