June 2007 - Posts

msmvps.com online again
Fri, Jun 29 2007 9:27

The msmvps.com site was down in the last 2 days, but it looks like the team solved the problem (which is cool :)).

while the site was down, i just got older and now I'm 31 :) (on the 27th to be precise). I've also spent some time looking at Silverlight and I'm still not sure if I should be investing any more time on it. I don't have any doubts that it's a really cool technology, but I'm a programmer (not a designer) and I believe I've seen most of the things it has to offer me (not all, since i still haven't taken a look at LINQ support, for instance).

On the other hand, I still haven't found anything else that makes me say: "wow, this is cool! I must really dive into this...". So, the biggest decision i need to make in the next days is: should I keep looking at Silverlight or should I change my focus to another area?

by luisabreu | 2 comment(s)
Filed under:
Working from home
Sun, Jun 24 2007 13:10

2007... and this (working from home) is still something close to impossible. not sure why, but it still looks like there are lots of people that think that workers produce more when they work on the office than when they work from home. most of them think that watching their workers is the key to insure better productivity.

 in my opinion, this is completly wrong, but it seems like nothing can make them change their minds. In fact, i've tried to measure my productivity at home and at work. In my case, i'm twice more productive when i work from home. how about you?

by luisabreu | 8 comment(s)
Filed under:
Silverlight: GOA controls
Sat, Jun 23 2007 14:04

A cool pack of 40+ controls for flash and silverlight. Go get them while they're free :)

by luisabreu | with no comments
Filed under:
31 days of Resharper
Fri, Jun 22 2007 19:43

Since there's a new release of this great tool, maybe it's reread the 31 days of resharper :)

MediaElement and local files: no luck on Silverlight
Fri, Jun 22 2007 17:42

When you look at the MediaElement object, it's obvious that it's really easy to use when you need to play a file and you know the location of that file. When you think about it, you have several options when you want to open a movie: you can download the movie before starting to play it (using a downloader and passing it to the media element object) or you can just hook up the Source property with a specific URI. Now the problem is when you want to play a local file. Yeah, Silverlight shouldn't let me access the user files. The problem is that you cannot get a path when you use the OpenFileDialog. You can get the name of the file or you can get the file's contents. However, you cannot get the path to it (and I've even tried using reflection over it, but it failed with an exception).

Now, the problem is that the MediaElement doesn't have any property or method that receives a stream. Now doesn't it look like something is missing here?

by luisabreu | 2 comment(s)
Filed under:
Book review: The non-designer's design book
Thu, Jun 21 2007 22:52

This short book is appropriate for everyone who needs to learn some basics about the principles of design. After presenting the basic principles, the author gives lots of examples that show how to improve some bad design examples. Since it's a short book, you'll be able to read it in 2 days. If you're like me, you'll want to read this book :)

My note: 6/10.

by luisabreu | with no comments
Filed under:
More tutorials on Silverlight and blend
Thu, Jun 21 2007 22:37

Man, these topics are hot! Here's another cool site that has some tutorials on these technologies.

by luisabreu | 1 comment(s)
Filed under:
Resharper 3.0 is out
Thu, Jun 21 2007 21:40

As always, there's also a 30 day trial version available. Check it out here!

by luisabreu | with no comments
Filed under:
Adding glyths to your silverlight apps
Thu, Jun 21 2007 11:58

Well, it ended up being easier than I though. You have two options: use the glyphs object or download the font using a downloader object and then associate it with the TextBlock object that has the text you want to show. There are already two excellent posts that show these options:

Converting the samples to managed code is so easy that I won't put it here :)

by luisabreu | with no comments
Filed under:
There's a new release of the AJAX toolkit
Thu, Jun 21 2007 9:40

And it seems like it solves some of the issues i've mentioned before. Delay has a great post that explains everything that you need to know about it.

by luisabreu | with no comments
Filed under:
Some ideas on how to integrate search on your ASP.NET applications
Wed, Jun 20 2007 22:49

A few weeks ago I spent some hours building some controls that ease the integration of search on a web site. My initial prototype consisted of two ASP.NET controls: a data source control and a composite control. Its objective was to search the web by using the MSN Search SOAP API. I documented the whole thing with some videos and power points presentations (everything in portuguese):

  • The MSNSearcherDataSource and MSNSearcherUI controls (video pptx)
  • MSNSearcherDataSource: how to build a data source control (video pptx)
  • MSNSearcherUI: how to build a composite control (video pptx)

And here's the source code for that initial prototype.

I then started thinking on  how I could expand this project in order to add aditional searching capabilities. The provider pattern seemed like the way to go and while i was making the changes to the initial version of the prototype, the May future bits went live and ended up influencing my code. Now, I've written this code at least a month ago (I think:)) but only today did i finished writing a small article that presents the main ideas that were behind the construction of this  prototype. The good news is that the article is in English :)

Without further ado, here are the links:

If you download the latest version of the code, you'll see that you have 2 demo sites. One shows how to use the existing controls against the default MSN Search provider. The second shows how to write your own provider (in this case, a provider that queries a simple database that stores info on some fruits).

As I say in the article, the main objective of this project is to share some ideas on how you can integrate searching in your ASP.NET pages. The current release ended up being heavily influenced by my initial problem (which consisted on using MSN to run searches) and by the release of the May preview bits while I was making the transition of the first to the second version. The latest release still needs some improvements (read the article to get more details), but i think the current version might be useful if you're trying to integrate search on your ASP.NET applications.

A final disclaimer: the code is as-is and you're free to use/change the code in whatever ways you see fit. Do notice that currently I'm not maintaining this code, though there's still the possiblity of creating a project on codeplex so that everyone can contribute to the current release...

by luisabreu | 3 comment(s)
Filed under:
Getting your initParams from managed code
Wed, Jun 20 2007 11:40

You can use the initParams property of the Siverlight control to pass aditional infomation during the creation of the control. There's already a property which should let you get it from managed code:StartupArguments. Unfortunately, it wil always return an empty string in the current release:

WebApplication.Current.StartupArguments

Yasser suggested a workaround for the current version untill we get a new release that lets us get the value correctly. His idea was to call a javascript method that will return that value (you need this because the InitParams is a property of the Silverlight control and in the current release there isn't a way to get a reference to that control from managed code). Doing this means that you'll have to:

  • build a new EventArgs class and annotate it with the Scriptable attribute
  • build a new event based on a new delegate and annotate it with the Scriptable attribute
  • annotate the class that exposes the event with the Scriptable attribute
  • register that class by calling the RegisterScriptableObject method

Lots of things for getting a string from JS code (btw, i've already talked about this sort of code here). So, why not simplify? I suggest just adding a string property to the class which will get called from the page. You get a little more coupling with this approach, but you reduce the code (and when you think about it, you have coupling in  both cases since things won't work if you're exposing an event and it doesn't get handled by the page!). Here's some managed demo code:

[Scriptable]
public partial class Page2 : Canvas
{
  public void Page_Loaded(object o, EventArgs e)
  {
     // Required to initialize variables
     InitializeComponent();
     WebApplication.Current.RegisterScriptableObject("SL", this);
  }

  private string _initParams; 
  [Scriptable]
  public string InitParams
  {
     get{return _initParams;}
     set { _initParams = value; info.Text = _initParams; }
  }
 

}

As you can guess by looking, the top canvas has a TextBlock inside that is used to show the values passed to the InitParams property. To test the page, lets o write the following JS code:

function createSilverlight()
{
     Sys.Silverlight.createObjectEx({
           source: "Page2.xaml",
           parentElement: document.getElementById("SilverlightControlHost"),
           id: "SilverlightControl",
           properties: {
               width: "100%",
               height: "100%",
               version: "0.95",
               background: "#ffffffff",
               isWindowless: false,
               enableHtmlAccess: true
          },
          events: {onLoad:handleLoad},
         initParams:"testing"
      });
}

And from the handleLoad method we initialize the InitParams property:

function handleLoad(sender){
   sender.content.SL.InitParams = sender.InitParams;
}

And that's it! Oh, there's a small gotcha: the InitParams isn't initialized during the load event of the top canvas object. So, if you have aditional logic that depends on that value, don't put it on a method that handles that event. In those cases, you'll have to tweak your code so that it'll only run after getting a valid value for the property.

by luisabreu | with no comments
Filed under:
Cool workaround for "complex" parsing in the current Silverlight alpha version
Wed, Jun 20 2007 10:55

In the current alpha version you can only have "simple" properties exposed by your controls. Trying to expose a complex property ends up generating a parsing exception. This limitation has been ackowledged by the team. Here's a cool workaround which you can use when you need to add collections of items in your control.

by luisabreu | with no comments
Filed under:
How can I submit my form from my C# Silverlight code?
Fri, Jun 15 2007 20:02

Simple: call one of the overloads of the static Submit methods exposed by the HtmlPage class:

HtmlPage.Submit();

HtmlPage.Submit( "formId" );

If you only have  a form on you're page, then using the first option is the way to go. if you have several forms, you need to specify the id of the form you're submiting and you need the second overload. Simple, right?

by luisabreu | 4 comment(s)
Filed under:
Silverlight: windowless property and transparent controls
Fri, Jun 15 2007 12:29

Today I've been playing with the Windowless property of the Silverlight control and seeing what can be achieved when you set this property to true. The first thing you should keep in mind is that this property can only be set during the creation of the control. You can always check the value of the property, but you cannot change its value after the control has been created.

Generally, you'll be setting this property to true when you want to get a "transparent" control (however, there are other scenarios where you need to set this property to true). When you want transparency, you need to do more than just set that property set true: for starters, you need to pay attention to the Background property of the control. Currently, you can define it in several ways. Some let you define the alpha value of color (check the help). When you use one of these approaches, the control takes that value into account and the result is a cool blend of the control's color with the current background color of the page (ie, of the HTML control that is used as a container).  For instance, the following code makes the control totally transparent:

Sys.Silverlight.createObjectEx({
  source: "Page2.xaml",
  parentElement: document.getElementById("SilverlightControlHost"),
  id: "SilverlightControl",
  properties: {
    width: "100%",
    height: "100%",
    version: "0.95",
    background: "#00ffffff",
    isWindowless: true,
    enableHtmlAccess: true
  },
  events: {onLoad:handleLoad}
});

Since I've set the alpha channel to 0, I'll get total transparency, letting you see what's on the page. On the other hand, setting it to ff would give me an opaque background color. 

Again, if you're looking for true "transparency", there's still a couple of extra details to keep in mind: pay attention to the background and opacity of your silverlight elements. For instance, if you run the previous code for creating an object and if you set the background color of your top Canvas to white without changing the default opacity you end up getting an "opaque control".

At the end of the day, getting true transparency means you need to:

  • set the Windowless property to true during the creation of the control;
  • pay attention to the background color's alpha value;
  • pay attention to the background color and opacity of the silverlight elements that you have in your pages.
by luisabreu | 1 comment(s)
Filed under:
Silverlight: extra parameter on the object that is passed to the createObjectEx method
Fri, Jun 15 2007 10:36

Scott's post leads me to thinking that (maybe) we need an extra parameter on the object that is sent to the createObjectEx method: ignoreVerifications. Setting this parameter to true would prevent all the verifications that are done on the Silverlight.js file during the creation of a new Silverlight control. It's true that there's already an ignoreBrowserVer parameter. However, this parameter will only prevent browser detection but it'll keep testing to see if the platform is installed. If you're letting me prevent browser detection, why not go a little bit further and let me cancell all the verifications? Just a thought...

by luisabreu | with no comments
Filed under:
Drag-n-drop on Silverlight alpha
Thu, Jun 14 2007 13:55

Today I've run some tests on drag-n-drop support available for the alpha version. It ended up being really easy to add this kind of behavior to a silverlight element. Lets start by defining some elements in XAML, which are placed inside a top canvas:

<Rectangle x:Name="r" Width="66" Height="80" Canvas.Left="41" Canvas.Top="40.537"
       Fill="red" />
<Rectangle x:Name="r2" Width="66" Height="80" Canvas.Left="200" Canvas.Top="40.537"
      Fill="Green" />
<Rectangle x:Name="r3" Width="66" Height="80" Canvas.Left="300" Canvas.Top="40.537"
      Fill="Blue" />

The idea is to let the user reorganize the rectangles on the canvas by dragging them around. The user must also be able to cancel the current drag operation by pressing the ESC key (I've used the KeyUp event to handle the ESC key press).

We start by hooking up several events of the rectangles during the Load event of the top canvas element:

r.MouseLeftButtonDown += new MouseEventHandler(down);
r2.MouseLeftButtonDown += new MouseEventHandler(down);
r3.MouseLeftButtonDown += new MouseEventHandler(down);

r.MouseLeftButtonUp += new MouseEventHandler(up);
r2.MouseLeftButtonUp += new MouseEventHandler(up);
r3.MouseLeftButtonUp += new MouseEventHandler(up);

r.MouseMove += new MouseEventHandler(move);
r2.MouseMove += new MouseEventHandler(move);
r3.MouseMove += new MouseEventHandler(move);

this.KeyUp += new KeyboardEventHandler(keyUp);

As you can see, we need to handle several mouse events. We also need to handle a key press because the ESC key must cancel the current drag operation! - that is, if there's one being done.

When the user clicks over a rectangle, we need to save the rectangle's current position and Z-Index because we must return the rectangle to its initial position when the user hits the ESC key during the dragging. So, we start by adding the following fields to the Canvas class:

bool _mouseCaptured = false;
double _currentX = 0.0;
double _currentY = 0.0;
int _initialZIndex = 0;
Rectangle _current = null;

And then we can proceed to the down method, that handles the MouseLeftButtonDown:

private void down(object sender, MouseEventArgs e)
{
  _current = (Rectangle)sender;

 _currentX = (double)((Rectangle)sender).GetValue(Canvas.LeftProperty);
 _currentY = (double)((Rectangle)sender).GetValue(Canvas.TopProperty);

 ((Rectangle)sender).CaptureMouse();

 _mouseCaptured = true;

 _initialZIndex = Convert.ToInt32( ((Rectangle)sender).GetValue( Canvas.ZIndexProperty ) );
 ((Rectangle)sender).SetValue<int>(Canvas.ZIndexProperty, 10);
}

Since this method marks the beginning of a drag operation, we must initialize our auxiliary fields. Notice the CaptureMouse method call...it's really important and it's saying that all mouse events should be redirected to the current Rectangle. The z-index value is changed to a "safe" value so that the dragged rectangle remains on the top of the other elements that exist on the page (for instance, in this example, if i didn't change the z-index and i started dragging the 1st rectangle, when this rectangle was over the second rectangle, it would be placed below that second rectangle because both have were declared with the same Z-order and the second was added after the first - not what we want in this case).

A drag operation needs to handle the mouse move (only if a drag is taking place). Here's the code to do that:

void move(object sender, MouseEventArgs e)
{
   if (!_mouseCaptured) return;

  ((Rectangle)sender).SetValue<double>(Canvas.LeftProperty, e.GetPosition(this).X);
  ((Rectangle)sender).SetValue<double>(Canvas.TopProperty, e.GetPosition(this).Y);
}

When the user moves the cursor and the dragging operation has started (_mouseCaptured = true), we only need to update the Left and Top properties of the Rectangle (note how we're passing this in order to use the top canvas as the reference for the X and Y  coordinates). When the user releases the mouse button, it's time to clear the auxiliary fields and to release the mouse capture:

private void up(object sender, EventArgs e)
{
   ((Rectangle)sender).ReleaseMouseCapture();

    _mouseCaptured = false;
    ((Rectangle)sender).SetValue<int>(Canvas.ZIndexProperty, _initialZIndex);
}

The only thing that is left is cancelling a dragging operation, which is done by the keyUp method:

void keyUp(object sender, KeyboardEventArgs e)
{
  if (!_mouseCaptured || e.PlatformKeyCode != 27 ) return;
  _current.SetValue<double>(Canvas.LeftProperty, _currentX);
  _current.SetValue<double>(Canvas.TopProperty, _currentY);
  _current.SetValue<int>(Canvas.ZIndexProperty, _initialZIndex);

  _current.ReleaseMouseCapture();

  _current = null;
  _mouseCaptured = false;
}

Again, nothing too complicated...we start by checking if we're on a dragging operation and if the user hit the ESC key. If any of those conditions isn't true, we don't do anything. If they are both true, we must put the rectangle at its original place (ie, we must put it where it was before starting the dragging operation).

by luisabreu | 6 comment(s)
Filed under:
Silverlight alpha: handling SL object's events from Javascript code
Thu, Jun 14 2007 9:37

You have several options for handling events fired by your SL objects in javascript. The first option is to hook up the event from Javascript code. In this scenario, you'll probably start by hooking up the onLoad event of the Silverlight control:

function createSilverlight() {
  Sys.Silverlight.createObjectEx({
       source: "Page.xaml",
       parentElement: document.getElementById("SilverlightControlHost"),
       id: "SilverlightControl",
       properties: {
          width: "100%",
          height: "100%",
          version: "0.95",
          enableHtmlAccess: true
       },
       events: {
           onLoad:handleLoad}
       });
}

Then, from the handleLoad method, you'll write the code for hooking up the required event:

function handleLoad(sender){
     sender.Content.FindName( "r" ).addEventListener( "MouseLeftButtonDown", "h" );
}

In the previous example, I start by getting a reference to an element (named r) and hook up the MouseLeftButtonDown event through the addEventListener method. It's interesting to note that by using the addEventListener method, you can hook up several methods with the same event (ie, it's possible to have several methods that handle the same event and they'll all be called when that event is generated). Oh, and if you've set up an event handler from managed code, it'll also be called when the event fires.

There's another option available: you can do it from the XAML by using the BLOCKED SCRIPT prefix. I'm not sure if this is a recommended approach, but it works. Lets walk through an example. When we have this:

<Rectangle x:Name="r" Width="66" Height="80" 
             Canvas.Left="41" Canvas.Top="40.537"
             Fill="red" MouseLeftButtonDown="h" />

we're saying that there's an h method in your codebehind file that handles the event. When you're using the 1.0 version, this means that the platform expects to find a Javascript method called h. However, when using the 1.1 version, it has a different meaning: in this case, you're supposed to have a managed method (ie, a method written in managed code) in your code-behind file. 

The interesting part is that if you use the BLOCKED SCRIPT prefix, it'll search for a Javascript h method:

MouseLeftButtonDown="javascript : h" (remove the space)

As I've said, I'm not sure if this is the intended usage, but it works...

by luisabreu | with no comments
Filed under:
Calling a Silverlight WCF service - part II
Wed, Jun 13 2007 22:32

Yesterday I showed one approach to call a WCF service from a silverlight page. Today, after some posts exchanges here, i ended up installing a VPC XP image and i was able to see that, on a clean installation (no VS 2005), you can get a proxy automatically by using the add web reference menu. So, if that is your case, then you do not need to write the code for the proxy I've showed yesterday (but you still need to configure your WCF service to use JSON).

by luisabreu | 2 comment(s)
Filed under:
Calling a WCF service from your Silverlight application
Tue, Jun 12 2007 23:43

Yesterday I talked about calling a traditional ASMX web service from your Silverlight app. Today, I'll be talking about WCF services. As I've said yesterday, in the current release, you only have tool support for getting a proxy to an ASMX web service (well, at least I've tried getting a web reference to a WCF service and it simply didn't work - maybe i'm doing something wrong). However, nothing prevents you from creating your own proxy to make the call to  a WCF service.

Since the alpha version only understands JSON when it calls ASMX services, I'm also assuming that is the only way you have to get info from a WCF service. That being the case, you must start by configuring your service to use JSON as its message enconding format.

After doing that, it's only a matter of  creating a new proxy class. Let me illustrate this with a quick example. Lets start by creating the dummy service:

[ServiceContract]
public interface ITest
{
    [OperationContract]
    S DoWork();
}

public class Test : ITest
{
    public S DoWork()
    {
        S a = new S();
        a.Address = "Funchal";
        a.Name = "Luis";
        return a;
    }
}

Don't forget to add the svc file :) (not shown here because there really isn't much to show, right). As you can see, this is really a stupid service which returns an object that only has two properties. Here's the S class (just for the sake of completeness):

[DataContract]
public class S
{
    [DataMember(Name="Name")]
    private string name = "Luis";
    [DataMember(Name="Address")]
    private string address= "Funchal";

    public string Name
    {
        get { return name; }
        set { name = value; }
    }

    public string Address
    {
        get { return address; }
        set { address = value; }
    }
}

Now, the fun begins :) You must start by definig the S class in your silverlight project. You can do this in several ways:

  • you can add an existing cs file and then choose the link option (instead of clickin in the add button);
  • you might have built a dll with the previous type and then add it as reference to the service and silverlight projects;
  • there's always the old copy/paste approach :)

After doing that, you need to build a new type (the proxy) which you'll be using to communicate with the service. You must really build a new class because all the cool methods of the the SoapHttpClientProtocol class that you need to make the service calls are protected (the truth is that nothing prevents you from using the BrowserHttpWebRequest class and then using the JavaScriptSerializer to serialize/deserialize the values. If you find this funny, then by all means, go ahead and do it; i prefer to build the class in 30 seconds and then hit the coach to watch tv :))  . Here's a simple proxy that lets you invoke the DoWork method in a sync fashion:

public class MyProxy:SoapHttpClientProtocol
{
            public S DoWork()
            {
                object[] obj = this.Invoke("DoWork", new ServiceParameter[0], typeof(S));
                return (S)obj[0];
            }
}

Do notice the new ServiceParameter[0] value passed as the 2nd parameter of the Invoke method (needed because the method doesn't receive any parameters; if it expected parameters, you just need to pack them in an array and pass them to the Invoke method)...Getting the async methods is as easy as adding 2 methods which call the BeginInvoke/EndInvoke methods inherited from the base class. Using the proxy is really simple, as you  can see from the following code:

MyProxy proxy = new MyProxy();
proxy.Url = "url to the service";
S aux = proxy.DoWork();
Debug.WriteLine(aux.Name +"-"+ aux.Address);

And that's all for today.

by luisabreu | 12 comment(s)
Filed under: ,
More Posts Next page »

Search

This Blog

Tags

Community

Archives

Syndication

Email Notifications

News




  • View Luis Abreu's profile on LinkedIn


    Follow me at Twitter

    My books

    Silverlight 4.0: Curso Completo

    ASP.NET 4.0: Curso Completo

    Portuguese LINQ book cover

    Portuguese ASP.NET 3.5 book cover

    Portuguese ASP.NET AJAX book cover

    Portuguese ASP.NET AJAX book cover