Jeff Blankenburg is a passionate technologist with a wide range of interests.
This website is dedicated to discussing the ideas that pass through his head.

The main header for this website was created using Microsoft Silverlight.
Install it to see what you're missing!

Get Silverlight to see the whole site!

TUTORIAL: How To Create A SetTimeout Function In Silverlight

Monday, June 15, 2009

I am in the process of creating my first game in Silverlight, and one of the first things that I noticed I was missing from my Javascript-era toolkit was the setTimeout() function.

In short, this little function is the be-all, end-all of Javascript animation. It is the device you use to insert little "pauses" into your code so that objects appear to be moving. Without it, your pieces would simply start at one position, and appear at the final destination. I use it primarily to make sure that the browser takes the time to draw each step of the animation. Here's an example of me using the setTimeout() function in Javascript, circa 1999 (it's also less than 5K in total size!):



1. Create a new UIToolkit Class.

It was tempting when starting this tutorial to just create a class that does one thing. But as I move forward in my Silverlight adventures, it occurs to me that we're probably going to encounter more of these types of needs in the future. So, I'm creating a UIToolkit class in my project. This will contain all of the little helper functions I create going forwards.

public static class UIHelper
{

}

2. Inherit from System.Windows.Threading.DispatcherTimer

We are primarily going to be using the DispatcherTimer as is, but we also need it to accept an Action to execute when the timer expires. So we will be creating a new class that inherits from the standard DispatcherTimer, adding an Action to its definition.

public class ActionTimer: System.Windows.Threading.DispatcherTimer
{
public Action Action { get; set; }
}


3. Create a setTimeout method in UIToolkit

To keep it familiar for the Javascript folks out there, I'm keeping the name of the method setTimeout. It's not even my usual casing, but for this example, I'm going to stick with the Javascript syntax.

Inside this method, we're going to need an instance of our new ActionTimer, including the interval we want, and the method to call, as well as the calls to kick off the timer, and an event handler to manage each tick of the timer. Here's the code:

public static void setTimeout(int milliseconds, Action action)
{
var timer = new ActionTimer
{
Interval = new TimeSpan(0, 0, 0, 0, milliseconds),
Action = action
};
timer.Tick += new EventHandler(timer_Tick);
timer.Start();
}

static void timer_Tick(object sender, EventArgs e)
{
var t = sender as ActionTimer;
t.Stop();
t.Action();
t.Tick -= timer_Tick;
}


Or, just copy this into a new class file


public static class UIToolkit
{
public static void setTimeout(int milliseconds, Action action)
{
var timer = new ActionTimer
{
Interval = new TimeSpan(0, 0, 0, 0, milliseconds),
Action = action
};
timer.Tick += new EventHandler(timer_Tick);
timer.Start();
}

static void timer_Tick(object sender, EventArgs e)
{
var t = sender as ActionTimer;
t.Stop();
t.Action();
t.Tick -= timer_Tick;
}
}

public class ActionTimer : System.Windows.Threading.DispatcherTimer
{
public Action Action { get; set; }
}


4. How to call our new method

Now that we've got a setTimeout method that takes a number of milliseconds and an action, we need to call it for testing purposes. Below is the syntax we'll be using. The major difference you'll notice between this and the Javascript implementation is that our new method will take an entire block of code as our Action. In Javascript, we're forced to concatenate a string of commands together, and it can get pretty messy fast. We are setting this up to call our method every 1000 milliseconds, or every ONE second.

UIToolkit.setTimeout(1000, () =>
{
OurRecurringMethodCallShouldGoHere();
});


Let's see it in action!

Click here if the Silverlight below doesn't load. Click here to download this sample code.







Get Microsoft Silverlight



kick it on DotNetKicks.com

Labels: , , ,

posted by Jeff Blankenburg, 8:50 PM | link | 0 comments |

TUTORIAL #5: Calling Javascript From Silverlight 2

Tuesday, September 23, 2008

In this post, I want to show you how incredibly simple it is to call a Javascript function from the managed code of your Silverlight application. We'll also be able to retrieve a value from that function, and return it to Silverlight. If you're just hunting for the syntax, just jump to step #6. This post covers creating everything from scratch, in both VB and C#.

1) Create your Silverlight project and sister web site.

I've already documented creating a new Silverlight project here, so I'll let you read that one first, if necessary.

2) Let's write a "legacy" Javascript function.

We need a JS function to call, so let's make it interesting. Let's say that I have some code from a previous app that determines all of the prime numbers from 1 to 500. I don't necessarily want to rewrite that, so let's just reuse it. Here's the code:


//The purpose of this code is to find all of the prime numbers under 500.
//The definition of a prime number is one that is only divisible by 1 and itself.
//We are utilizing the Sieve of Eratosthenes to enhance our algorithm.
var primeArray = new Array();
var primecounter = -1;
var primeFlag = true;

function getPrimes(useri){
     primeArray.length = 0;
     primecounter = -1;
     var i = 500;
     if (useri != ""){
          i = useri;
     }
     for (j=1;j<=i;j++) checkForPrime(j);
          return primeArray.join(" ");
}
function integerCheck(newvalue){
     var regexp = /(^\d\d*$)/;
     if(regexp.exec(newvalue)) primeFlag = false;
}
function checkForPrime(j){
     primeFlag = true;
     for (k=0;k<=primecounter;k++){
          if ((primeArray[k] != "")&&(primeFlag)){
               if ((j/primeArray[k] != 1)&&(j/primeArray[k] != j)){
                    integerCheck(j/primeArray[k]);
               }
          }
     }
     if (primeFlag){
          primeArray[primecounter+1] = j;
          primecounter++;
     }
}


3) Add that JS code to our web page.

Just add a <script> block in the <head> of your web page, and put the above code inside. Done!

4) Now we need to write some XAML.

Open your Page.xaml file that was created for you, and let's add a button. We'll use this button's event handlers to call our Javascript function eventually. To add a button, here's the XAML I am using inside of the <Grid> I was provided:


<Button Width="100" Height="50" Content="Get Primes!" />


5) Add an event handler to our button.

In our button, add the "Click" property, and Intellisense will prompt you to create a "New Event Handler." This will create the method in the code behind file for you. Here's the new button XAML:


<Button Width="100" Height="50" Content="Get Primes!" Click="Button_Click" />


6) Time to call that Javascript function.

Jump into the code behind file for your XAML (page.xaml.cs or page.xaml.vb by default). There's a new method called Button_Click for you. We are going to write ONE line of code to make this happen. And here it is:

C#

HtmlPage.Window.Invoke("getPrimes");

VB

System.Windows.Browser.HtmlPage.Window.Invoke("getPrimes")


I kinda lied though on the 1 line of code thing. For C#, we also need the "using System.Windows.Browser;" statement. The "getPrimes" value we are passing is the name of the Javascript function we want to call. But this only gets us halfway there. My JS function creates a list of prime numbers and then sends them back as a return value. So we need to actually do something with this value.

7) Refactoring our code to use the return value.

So we know we can call a Javascript function, but returning the value is going to be a little more challenging. We need to capture the return value, cast it as a string (everything from Javascript is assumed to be an object), and display it in our Silverlight app. But let's make it a little more interesting. Let's also change things to pass parameters to our JS function as well.

First, we need some new XAML elements. I've added a <TextBlock> to my XAML page to display the primes, as well as a <TextBox> to gather the number of primes the user wants to generate. Here's the new XAML code:


<StackPanel x:Name="LayoutRoot" Background="White">
     <TextBlock Width="400" Text="Primes to what number?" TextAlignment="Center" />
     <TextBox Width="100" Height="24" x:Name="primecount" Margin="0,0,0,10" />
     <Button Width="100" Height="50" Content="Get Primes!" Click="Button_Click" />
     <TextBlock x:Name="primebox" Width="800" TextWrapping="Wrap" />
</StackPanel>

And now here's my new C# and VB code inside my Button_Click methods to pass our value and display this data:

C#

string primeArray = (string) HtmlPage.Window.Invoke("getPrimes", primecount.Text);
primebox.Text = primeArray;

VB

Dim primeArray = System.Windows.Browser.HtmlPage.Window.Invoke("getPrimes", primecount.Text)
primebox.Text = primeArray.ToString


What will happen in this scenario is that if the user provides a value, we will use it, and if they don't, we'll default to 500.

8) So let's run it!

That's it! We've successfully called a Javascript function from Silverlight (in both C# and VB), retrieved the value it created, and displayed it in our application. We also passed specific parameters to that Javascript function to influence its behavior. Click the Demo button to see it in action.



9) Source Code Links

I've provided the source code for this example in both C# and VB. Just click the appropriate button.

C#.NET Source Code VB.NET Source Code

kick it on DotNetKicks.com

Labels: , , , , , ,

posted by Jeff Blankenburg, 12:21 PM | link | 3 comments |

TUTORIAL #2: Using Javascript To Call A WCF Web Service

Wednesday, September 03, 2008

Sometimes you just need to use Javascript. It's one of those things that web developers claim to hate, but secretly, I just hated the lack of tools support for it. That seems to be solved, at least for me.

Today I'm going to show you how to call your asynchronous web service from Javascript, and how we can incorporate JS Intellisense to make our job infinitely easier (one line of code, anyone?) The source code is provided at the end, in both C# and VB.NET.

1) Let's start with a new web application project.

Solution Explorer

2) Next, we're gonna need a web service to talk to.

image

Now, you may already be saying to yourself, "Jeff, this is all well and good, but I already have WCF services created. We don't all have the luxury of creating stuff from scratch each time!" I've got you covered. There's actually only one line of code that changes a WCF service into an AJAX-enabled WCF service. And here it is:

[ServiceContract(Namespace = "")]
 //The following line is the one you need!
 [AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
 public class JeffsName
 {
  [OperationContract]
  public string GetJeffsName()
  {
   return "Jeff Blankenburg";
  }
 }


One you've got your WCF service up and rockin, we need to get it to DO something, right?



3) Getting our method to DO something

For this tutorial, I'm not going spend time talking to a database or anything extravagant. But I want to do more than return a name. I was talking with a friend of mine yesterday about why the nickel seems to be the rarest of coins in your pocket, and that inspired my method for this example.

<LONGSTORY TYPE="INTERESTING" VALUE="NOT IMPORTANT TO THE TUTORIAL">

Dan pinged me over IM to tell me about this guy who had started a game collecting money on the street. He called it the "Change Race." He wanted to see who could collect $100 faster by ONLY collecting money that was "found." It didn't count if you found $5 in an old coat from the previous winter, that was still your money.

Anyway, so Dan, who is known to like to try eccentric things like these, thought he would give it a go. In his coin finding history to this point, he discovered that he was finding significantly fewer nickels than any other coin. Here's the breakdown:

$0.25 - 7

$0.10 - 16

$0.05 - 6

$0.01 - 63

Yes, there are only 7 quarters, but who drops a quarter and leaves it? I certainly understand those pennies, however. But only 6 nickels? That seems surprising, as I'm calling it, "The Silverier, Fatter Penny."

So the conversation we had was about WHY there seems to be fewer nickels. We threw around many theories, but ultimately came up with the fact that there are fewer change scenarios where a nickel is necessary. In addition, there's rarely a time where you are going to get 2 nickels in change, because you're more likely to get a dime. Anyway, I'd love to see a debate about this in the comments. There's even a good article someone wrote about "The Mystery of the Vanishing Nickel."

</LONGSTORY>

So that story led me to think about the 99 change scenarios that are possible when receiving change from a cashier. 1 cent through 99 cents. Zero doesn't count because you would just get bills (or nothing at all.)

My web service is going to take an integer value and return the fewest number of coins necessary to make that change. If your integer is greater than 99, I just subtract out the dollars until we are left with the change.

Here's my web service method:

public class ChangeScenario
 {
  [OperationContract]
  public string GetMinimumCoins(int changevalue)
  {
   int quarter = 0;
   int dime = 0;
   int nickel = 0;
   int penny = 0;
   int tempvalue = changevalue;
   while (tempvalue > 0)
   {
    if (tempvalue >= 100)
    {
     tempvalue -= 100;
    }
    else if (tempvalue >= 25)
    {
     tempvalue -= 25;
     quarter += 1;
    }
    else if (tempvalue >= 10)
    {
     tempvalue -= 10;
     dime += 1;
    }
    else if (tempvalue >= 5)
    {
     tempvalue -= 5;
     nickel += 1;
    }
    else if (tempvalue >= 1)
    {
     tempvalue -= 1;
     penny += 1;
    }
   }
   return "You need " + changevalue + " cents in change.<BR/><BR/>You get " + quarter + " quarters, " + dime + " dimes, " + nickel + " nickels, and " + penny + " pennies";
  }

In all, I take an integer parameter, and return a string that represents the fewest coins that will satisfy that change scenario.

4) Making the page aware of the web service

I wish I could say that this was now as easy as writing a line of code in a script block and you're done. But it's maybe 5 lines of code more complicated than that. And most of those lines are dedicated to letting the .aspx page know that you want to talk to the web service.

So speaking of that, I will need to add my all-too-familiar-scriptmanager to the page, as well as a reference to the web service we want to use.

<form id="form1" runat="server">
    <asp:ScriptManager runat="server" ID="sm">
        <Services>
            <asp:ServiceReference Path="~/ChangeScenario.svc" />
        </Services>
    </asp:ScriptManager>
    <div id="valuebox">
        <a href="javascript:callWebService();">Click to call web service.</a>
    </div>
</form>
You'll notice that I also have a DIV tag in there, with an ANCHOR tag calling a Javascript function. Inside this function is where I will call my web service method.

5) Calling the web service from Javascript

Now I have created a Javascript function at the top of my page, and I need to make that call to my web service. The syntax is generally what you would expect to find:

<script language="javascript" type="text/javascript">
    function callWebService()
    {
        ChangeScenario.GetMinimumCoins(86, setText);
    }
 
    function setText(changetext)
    {
        var myElement = document.getElementById('valuebox');
        myElement.innerHTML = changetext;
    }
</script>

The one thing that stuck out to me in all of this was the second parameter in the method call. It's the name of another Javascript function. This new ability also gives us some new Intellisense.

Javascript Intellisense

The first value is the parameter that the web service method takes. In this case, it's even expecting an integer. The second is the name of the Javascript function you want to be called upon successful completion of the asynchronous call. The third is another JS function for when the call fails.

So, when we click our button, we call the callWebService() function, passing in an integer value to determine our change.

In turn, it returns our value successfully, and calls the setText() Javascript function with the parameter our method returns.

This function then renders that value as the HTML for the DIV we have on the page.

6) Summary of our adventure

As I demonstrated, in rather verbose fashion, it's pretty simple to talk to a web service from Javascript directly. Most of your effort will be spent writing a service far more valuable than mine. The nice part is that the asynchronicity of the calls is completely handled for you.

Please let me know if you have any questions...I'd be glad to help you out.

7) Let's see this code in action!

I have uploaded my sample application for demonstration of this code. It has been slightly modified, so that we call the web service 99 times, once for each "change scenario." One thing that I have noticed, at least in my environment, is that because we are making asynchronous calls, they don't always return in the order they were sent. So you'll see that, even though we are making the calls in the order from 1-99, they don't necessarily get written to the page in that order. We're just taking the data as it returns.

demo

8) Source Code Links

Even though I provided my examples above in C#, I have provided source code for both C# and VB implementations of this example. Enjoy!

C#.NET Source Code VB.NET Source Code



kick it on DotNetKicks.com

Labels: , , , , ,

posted by Jeff Blankenburg, 4:11 PM | link | 3 comments |

Search

My Sponsor


My Badges



Follow Jeff Blankenburg on Twitter