MS AJAX Lib beta is out
Fri, Nov 20 2009 14:10

You can get it from here. I’m curious to see if it contains new features…

Reactive Extensions for .NET
Fri, Nov 20 2009 13:58

I’ve just noticed this post from the Parallel team. Now, this will be useful because it seems like it solves lots of the bugs introduced in the latest public CTP of the Parallel lib :)

by luisabreu | with no comments
Filed under:
XAML: what about events?
Thu, Nov 19 2009 12:54

A friend of mine asked me about events and XAML: can we setup event handlers in XAML? And the answer is, yes, you can. Here’s a quick example of how you can handle the click event of a button:

<Button Click="Button_Click"></Button>

And yes, you must define the Button_Click method in your code-behind file (note that you could do it inline – ie, in the XAML file – if you’re using WPF). I must confess that I’m not really a fan of this approach since I prefer to put all my code in the code-behind file. For making it work, I’ll need to change the previous code slightly by adding a name to the button:

<Button x:Name="bt"></Button>

And now, from within the constructor, I can setup my event handler like this:

bt.Click += Button_Click;

Final note: in the real world, I’ll probably end up with a Lambda expression for simple handlers. As you can see, setting up handlers from the XAML is possible (the syntax is the same as you’ve got for props) but I don’t really recommend it. And that’s it for now. In the next post, we’ll talk about Silverlight’s markup extension support. Stay tuned.

by luisabreu | with no comments
Filed under: ,
How to build types that can be consumed from XAML
Thu, Nov 19 2009 10:32

Now that you know how to use custom types in XAML, you might be wondering if there are any thing you should keep in mind when designing new types that should be consumed from XAML. I’ve already said before that collection properties need to have a getter that return a valid instance of an object. But there’s more. Here are a few things you should consider when designing types for being consumed from XAML:

  • Elements can only be public classes which have a public parameterless constructor (notice that nested classes aren’t supported);
  • structs are usable from XAML too (consider using a type converter in some scenarios where you don’t want to use the default constructor to initialize the struct)
  • non-collections properties which reference objects (ie, not primitive types) should ensure that the type has a default constructor (or that the type or property that is being defined has an adequate type converter);
  • you should use type converters when you’re using a reference type which does not have a default constructor (or when you’ve used an abstract type as the type of a property).

Regarding collections, you’ve already seen the requisites for using them from XAML: the type should implement the IList or the IDictionary/IDictionary<TKey, TValue> interfaces.

And I guess this sums it up quite nicely. Stay tuned for more on Silverlight.

by luisabreu | with no comments
Filed under: ,
Associating XAML namespaces to CLR namespaces
Thu, Nov 19 2009 10:10

Take a look at the following (simple) XAML:

<UserControl x:Class="SilverlightApplication1.MainPage"
    xmlns=
"http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"> <Canvas x:Name="myCanvas"> </Canvas> </UserControl>

When I started talking about XAML, I said that the default XAML namespace is associated to several controls. You might be a little curious on how this is done. By using Reflector, you’ll see that many of the Silverlight assemblies associate CLR namespaces to XAML namespaces through the XmlnsDefinitionAttribute:

xmlnsdefinitionattribute

You’ll typically find this attribute in most assemblies that have been thought with Silverlight and WPF in mind. Notice, though, that its use isn’t mandatory to map a CLR namespace to XAML namespace because Silverlight (and WPF) supports a special mechanism for doing that. For instance, suppose you’ve got a type called BeautifulGrid, defined in the CLR Test namespace, in a Dumb assembly. Now, when you build the assembly, you didn’t knew anything about the XmlnDefinitionAttribute. How can you use the BeautifulGrid in your XAML file? Here’s the answer:

<UserControl x:Class="SilverlightApplication1.MainPage"
    xmlns=
"http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:my="clr-namespace:Test;assembly=Dumb"> <Canvas x:Name="myCanvas"> <my:BeautifulGrid> </my:BeautifulGrid> </Canvas> </UserControl>

There are some interesting gotchas  you should keep in mind when using this syntax:

  • the clr-namespace key is separated from its associated value by a semi-colon (:) while the assembly part of the expression uses an equal sign (=)
  • this is one of those places where you *can’t* use white spaces for improved readability;
  • you can omit the assembly part if the namespace you want to use is in the same assembly as the “current” XAML file.

Even though Silverlight supports the XmlnsDefinitionAttribute, the truth is that it doesn’t really play an important role for using custom types in Silverlight. The recommended approach for using custom types in XAML is to use the clr-namespace approach I’ve showed above.

And that’s it for now. Stay tuned for more in Silverlight.

by luisabreu | 2 comment(s)
Filed under: ,
South Africa 2010: here we go, here we go!
Wed, Nov 18 2009 21:49

A friendly advice to the Bosnian coach: next time, play more and talk less!

by luisabreu | with no comments
Filed under:
XAML languages features
Wed, Nov 18 2009 15:15

As I’ve said before, Silverlight supports only a subset of the existing XAML keywords you can use in WPF. Here’s the list of keywords you can use in your Silverlight:

  • x:Class: you can apply this attribute to the root element of the XAML file (or object tree) that is going to be “compiled”. When you apply this attribute, you’ll end up creating a partial class (named after the value you’ve passed to the attribute) which is joined with the associated code-behind file. Even though you don’t really have to use this attribute, the truth is that you’ll probably use them in 99% of your XAML files;
  • x:Key: as you’ve seen in the previous post, you can use this attribute to set the key of a dictionary’s entry of a resource dictionary;
  • x:Name: used for identifying an object so that it can be easily recovered from the code-behind file. The “practical effect” of using this attribute is that you’ll end up having a field in the code-behind file which references the element you’ve defined on the XAML file. As you can see on the docs, you’re limited in the values you can pass to this attribute. It goes without saying that you must ensure uniqueness through the names you give to the elements;
  • x:Null: this *extension* is used for setting the value of a property to null. You can use this extension with the property element or attribute syntax.

The best way to understand these attributes is to build a demo user control and see what happens after everything is compiled. For instance, lets assume that we’re adding a new Silverlight User Control to an existing Silverlight application (this will let me show what happens when you use the x:Class and x:Name attributes). By doing that, we end up with two files: a XAML and its corresponding code-behind CS file (shown in the next figure).

xamlandcodebehind

Here’s the default generated XAML (I’ve removed the unnecessary namespaces):

<UserControl 
 x:Class="SilverlightApplication1.SilverlightControl1"
 xmlns=
"http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" mc:Ignorable="d" d:DesignHeight="300" d:DesignWidth="400"> <Grid x:Name="LayoutRoot" Background="White"> </Grid> </UserControl>

If you look at the properties of the XAML file, you’ll see that it looks like this:

xamlprops

The default configuration ends up embedding the XAML file in the assembly (check the next image):

xamlresources

You’ll also get a new C# file (.g.cs) from the XAML “compilation” (onde again, I’ve edited the code before pasting it here):

namespace SilverlightApplication1 {
 public partial class SilverlightControl1 : 
System.Windows.Controls.UserControl { internal System.Windows.Controls.Grid LayoutRoot; private bool _contentLoaded; [System.Diagnostics.DebuggerNonUserCodeAttribute()] public void InitializeComponent() { if (_contentLoaded) { return; } _contentLoaded = true; System.Windows.Application.LoadComponent(
this, new System.Uri(
"/SilverlightApplication1;” +
“component/SilverlightControl1.xaml"
,
System.UriKind.Relative)); this.LayoutRoot = ((System.Windows.Controls.Grid)
(
this.FindName("LayoutRoot"))); } } }

There are several interesting things going on here:

  • the x:Class attribute is responsible for the creation of the partial class defined in the .g.cs file;
  • all the named elements (ie, all the elements that use the x:Name attribute) get added to this partial class as fields. Notice that the FindName method is used for grabbing a reference to an element that is defined through the XAML file;
  • the LoadComponent method is used for loading the XAML defined in the XAML file. In this case, the generated code is getting the embedded XAML file from the SiverlightApplication 1 assembly.

by now, you should be able to understand why you can use the same name you’ve used for the x:Name attribute to access that element from a code-behind file. 

As you’ve seen, you can access the XAML elements from your code behind because building a Silverlight project ends up generating a partial class which introduces fields with the same name as the ones you used for the elements defined through XAML. THis is only possible due to the use of the x:Class and x:Name attributes.

And that’s it for now. Stay tuned for more on Silverlight.

by luisabreu | with no comments
Filed under: ,
XAML and collections
Wed, Nov 18 2009 12:13

We’ve already talked about several features related to XAML. In this post, we’ll keep going and we’ll see how to specify collections in XAML. There are two basic types of collections you can use in XAML: lists and dictionaries. Before going on, it’s important to understand that you’re not really creating new collections in XAML; instead, we’re adding items to existing collections (in other words, if you’re building an object which has a collection like property and you want it to be set from XAML, then don’t forget to make sure that the getter returns a valid reference to a collection object).

“List collections” are collections which expose an Add method (generally, we’re speaking about objects which implement the IList interface). In these cases, you’ll typically put the elements within the collection property and the XAML parser will create an object that represents each item before adding them to that collection through the Add method:

<Rectangle Width="300" Height="150">
    <Rectangle.Fill>
      <LinearGradientBrush StartPoint="0,0" EndPoint="1,1">
        <LinearGradientBrush.GradientStops>
          <GradientStop Color="White" Offset="0" />
          <GradientStop Color="Black" Offset="1" />
        </LinearGradientBrush.GradientStops>
      </LinearGradientBrush>
    </Rectangle.Fill>
</Rectangle>

Btw, we could have simplified the XAML because GradientStops is the content property for the LinearGradientBrush object:

<Rectangle Width="300" Height="150">
    <Rectangle.Fill>
      <LinearGradientBrush StartPoint="0,0" EndPoint="1,1">
       <GradientStop Color="White" Offset="0" />
       <GradientStop Color="Black" Offset="1" />
      </LinearGradientBrush>
    </Rectangle.Fill>
</Rectangle>

You can always write the previous code in C# (assume rect is a reference to the rectangle):

rect.Fill = new LinearGradientBrush()
{
    StartPoint = new Point(0, 0),
    EndPoint = new Point(1, 1),
    GradientStops = {
             new GradientStop()
            {
                Color = Colors.White,
                Offset = 0
            }
            ,
            new GradientStop()
            {
                Color = Colors.Black,
                Offset = 1
            }
    }
};

Dictionaries are a different kind of collection: in these cases, each entry is a pair composed by a key and a value. The important thing here is understanding that you specify the key through the x:key attribute:

<UserControl.Resources>
    <Color x:Key="Black" A="0" B="0" G="0" />
</UserControl.Resources>

For now, lets forget that we’re specifying resources and we’ll only concentrate on the syntax. As you can see, we added a tag which identifies the resource as a color and we’re identifying it with the word Black (ie, Black is the key that identifies this entry). Once again, you could translate the previous code into C# (Resources is an object of type ResourceDictionary), but I’ll leave it to you (if you don’t have anything better to do, that is :) )

Notice x:Key is one of the few XAML keywords Silverlight supports. Besides it, there’s also the x:Class, the x:Name and x:Null attributes (we’ll come back to them in a future post). If you’re coming from WPF, then this might seem limited at first, but it’s all we have in Silverlight.

And I guess this sums it up for now. Stay tuned for more on Silverlight.

by luisabreu | 2 comment(s)
Filed under: ,
Type converter on Silverlight
Wed, Nov 18 2009 11:09

Today we’ll talk a little bit about the role played by type converters in “transforming” XAML into C# objects. Here’s a quick example:

<Button xmlns=
"http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" x:Name="bt" Click="bt_Click" Width="100" Content="Say Hi" Background="Red" />

If you look carefully, you’ll see that Background expects a Brush object. All XAML attribute are strings by default. In  other words, you’d need the following C# code to set the background of the button:

bt.Background = new SolidColorBrush(Colors.Yellow);

So, what’s going on here? Well, it’s simple: the parser uses a type converter to convert the string into the correct object. In practice, type converters are objects which inherit from TypeConverter class. You can associate a type converter to a type or to a property by using the TypeConverterAttribute. The parser will respect that option and will use the indicated type converter to translate the string into the expected object type.

Now, unlike WPF, where everything is really based on managed type converters, in Silverlight, there is an *unmanaged* type converter which is used for performing most of the common conversions you’d expect to happen (take a look at the internal SilverlightTypeConverter class and you’ll notice that you’ll end up using the “unmanaged” XcpImports type).

So, don’t expect to find many type converters by firing up .NET Reflector. Btw, you should keep in mind that you can still build and use your own type converters for your types. The XAML parser will always check the current property and/or type and if it’s associated with a managed type converter, it will honor that relationship and your converter will be used.

And I guess it’s all for now. Stay tuned for more on Silverlight.

by luisabreu | with no comments
Filed under: ,
Plano Inclinado: Portuguese talk show which looks at how things are in the real “Portugal”
Tue, Nov 17 2009 12:37

If you’ve missed it, then don’t forget to check it online. It’s really a shame that most Portuguese people won’t ever watch this program (which is probably one of the first programs with real quality in Portugal) because they’re watching soap operas or some other low quality programs…

by luisabreu | with no comments
Filed under:
XAML: using content properties
Tue, Nov 17 2009 12:06

In the previous post, we’ve seen that we can use one of two approaches for setting the value of a property: we can use the property element or the attribute syntax (and, as we’ve seen in the previous post, you can’t use them both interchangeably). In this post, we’ll keep going and we’ll see how content properties simplify even more the markup we need to write to setup the value of a property.

For instance, here’s how I’d set the Content of a button to an image:

<Button xmlns=
"http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" x:Name="bt" Click="bt_Click" Width="100"> <Image Source="/p52.jpg" Stretch="UniformToFill" /> </Button>

If you compare this snippet with the one we had before, you’ll notice that we’re not using the <Button.Content> markup element to specify that we’re setting the Content property. Why?

To understand what’s going on, we need to talk a little bit about content properties. Any class can designate a property that should be set to whatever content is inside the XML element. As you’ve probably guessed, these properties are called content properties.

In the case of the Button class, its content property is the Content property. Specifying a content property is done through the ContentPropertyAttribute. For instance, in the case of the Button element, we need to look at the ContentControl class (used as base) to see how the content property is defined:

[ContentProperty("Content", true)]
public class ContentControl : Control
{

Whenever you see this attribute, you know that the content of element is directly “transformed” and copied to the indicated property. And that’s it for now. Stay tuned for more on Silverlight.

by luisabreu | with no comments
Filed under: ,
XAML and property elements
Tue, Nov 17 2009 10:20

In the previous post, we’ve started looking at same basic XAML. At the time, we’ve defined a simple button by using the following syntax:

<Button xmlns=
"http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" x:Name="bt" Content="Say hi" Click="bt_Click" />

In the previous snippet, we’re setting the Content property and the Click event. Btw, and in case you’re wondering, events are set up before the properties. This is the only thing you can take for granted (you can’t really depend on the order of the attributes in your XAML to influence the order by which properties are set). This makes sense because it means that eventual handlers will be called if an event is generated by setting a property to a specific value.

If you look at Content’s definition, you’ll see that it expects an object. That means we can, for instance, pass it an image instead of setting it to text:

<Button xmlns=
"http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" x:Name="bt" Click="bt_Click" Width="100"> <Button.Content> <Image Source="/p52.jpg" Stretch="UniformToFill" /> </Button.Content> </Button>

The previous snippet is showing the property element syntax. You should use it whenever you can’t use a simple string to define the value of a property. Property element syntax is really simple: you define a property by combining the name of the element with the name of the property. Property element syntax and attribute syntax are the two options you’ve got for setting the value of a property in XAML (sort of: we’ll leave content properties and collection properties to a future post).

In case you’re wondering, you can’t use something like this in Silverlight:

<Button xmlns=
"http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" x:Name="bt" Click="bt_Click" Width="100"> <Button.Content> Say Hi </Button.Content> </Button>

If you try loading the previous XAML, you should get an exception which says something like “Say Hi isn’t allowed as the button’s content”. In case you’re wondering, this does work in WPF. Unfortunately, in Silverlight you’ll have to use the attribute syntax for setting the value of the Content to a string.

In this cases, you do need to use another element. Here’s the code you can use for setting the Content’s property to text through the property element syntax:

<Button xmlns=
"http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" x:Name="bt" Click="bt_Click" Width="100"> <Button.Content> <TextBlock>Say Hi</TextBlock> </Button.Content> </Button>

Fair enough: this isn’t really similar to what we had before, but it’s really the only way to set the button’s Content property to something that looks like text (notice that in this case, the Content is set to another FrameworkElement and not to a simple string).

Understanding why something works in WPF and not in Silverlight is not complicated: you just need to keep in mind that all the features considered not essential were removed in order to control the size of the Silverlight framework. And it looks like this was one of them…

You must be wondering which syntax you should use when you want to set the value of a property. Sometimes, the answer is simple since we’ve seen a case where you can’t use both syntaxes for setting a specific value. When both approaches are supported, I’ll tend to use the one which is more compact (typically, this means going with the attribute syntax whenever possible).

And I guess this wraps it up for now. Stay tuned for more on Silverlight.

by luisabreu | 2 comment(s)
Filed under: ,
Introducing XAML
Mon, Nov 16 2009 21:16

You can’t really do it any other way: we must understand XAML before going on (at least, its basic features). In this post, we’ll start looking at XAML and at how we can use it to define the UI of our Silverlight user controls. So, the big question: what is XAML? To me, XAML (which, btw, means Extensible Application Markup Language) is a declarative language which you can use to define and initialize objects. Notice that XAML isn’t Silverlight specific. If my memory is correct, it was introduced with .NET 3.0 and its new frameworks (WPF and WF). In Silverlight, we’ll be using it to define the looks of our UIs. As we’ll see, it really saves us lots of code.

Ok, since this is a an intro post, we’ll start simple. In this post, we’ll talk about how we can create objects and set its properties. Here’s a simple XAML snippet:

<Button xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"    
    x:Name="bt" Content="Say hi" Click="bt_Click" />

XAML is an XML language. That also means that XAML is case sensitive. Notice that we’re talking about element and attribute names here. Values are a special case: sometimes they are case sensitive; others, they aren’t (more about this in future posts). The previous example already introduces two important concepts: it shows us how to declare an element in XAML  and how to set its one of its properties.

Btw, the previous code is equivalent to the following C# code:

var bt = new Button();
bt.Content = "Say hi";
bt.Click += (s, args) => { };

Ok, there’s a slight difference between both snippets: in the XAML snippet, we’re saying that the Click event will be handled by a method named bt_Click, while on the C# example, we’re using a Lambda expression.

I’m not sure if you’ve noticed, but we had to use a couple of namespaces when we wrote the XAML. The default namespace (http://schemas.microsoft.com/winfx/2006/xaml/presentation) is hardcoded to several CLR namespaces (notice that I haven’t found the list, but I assumed this behavior because that was what happened with WPF 1.0). The other namespace (the XAML one that is associated to prefix x) is used for defining some directives which are interpreted by the XAML parser (notice that the directives really look like attributes, but they are, in fact, directives). In the previous XAML snippet, the x:Name directive ends up creating a new Button object named bt (in a future post, we’ll see how this is done).

The x:class directive is another XAML directive that is used often when you need to associate a XAML file to a class defined in a code-behind file (oh yes, Silverlight does support code-behind files too :) ).

We’ve just started scratching XAML. As we’ll see in future posts, there are several interesting things we can do. For now, the main thing to keep in mind is that all that you can do through XAML, you can also do from C# code (though, as I’ve discovered recently, XAML code might be more performant than writing C# code – at least, when you think about rendering). And that’s it for now. In the next post, we’ll talk about the options we have for setting the properties of an object. Stay tuned for more on Silverlight.

by luisabreu | 4 comment(s)
Filed under:
New Security model for .NET 4.0
Mon, Nov 16 2009 11:41

It seems like CLR 4.0 will introduce a new security model (which looks a lot like the one we’ve got in Silverlight). Shawn Farkas has an excellent post which compares the two rule sets and explains what happens in several scenarios.

by luisabreu | with no comments
Filed under: ,
Getting started with Silverlight
Mon, Nov 16 2009 11:08

Last Friday, I’ve decided to start looking at Silverlight. This time, I’ve opted for starting with a book (generally, I prefer to go through the source code and run some tests along the way;). As usual, I’ll be writing a couple of posts to describe my experiences with this platform. Even though I don’t have much to say yet, I thought I’d better start writing about my experiences so that I don’t forget to mention anything along the way.

The first thing I noticed after writing  the “Hello, world!” app was that the contents of my Silverlight app are packaged into a xap file.

xapdeploy

A xap package is just a zipped file with the contents of your Silverlight application. If you open the file with an app like winrar, this is what you’ll see:

xapcontent

As you can see, the xap file contains all the resources of your app +  a manifest file (besides assemblies, you’ll typically end up with other resources like xaml files, images, etc.). Besides simplifying deployment, xap files end up improving the performance of an app. To understand why, just think that with xap, you end up compressing stuff and you’ll get all the stuff your Silverlight app needs in one request. And i guess this is all for this intro post. Stay tuned for more on Silverlight.

by luisabreu | with no comments
Filed under:
No more hacks for the MS AJAX’s binding problem
Fri, Nov 13 2009 9:26

At least, when the RTM version is released!

Ok, I guess you need some context: in the previous post, I talked about a problem which was mentioned to me by Andy in the comments of an existing post. The problem was that the __msajaxBindings field ended up being added to an object used in a live binding and that really means trouble when you try to serialize it (because you end up with a cyclic reference which generates a runtime exception).

In the previous post, I suggested a hack for it. Fortunately, Dave saw it and emailed me assuring that the hack won’t be necessary and that the internal __msajax… fields should only be added to HTML elements. As you’re probably expecting by now, the problem I mentioned in the previous post is the result of a bug (which will be solved before the RTM is out).

After being alerted by Dave, I’ve decided to take a closer look at the code…And yes, there’s a problem and it’s on the Sys.UI.DomElement.isDomElement method. This method ends up invoking the _isDomElement method which has a check that returns a “false positive”:

Sys._isDomElement = function Sys$_isDomElement(obj) {
   var val = false;
   if (typeof (obj.nodeType) !== 'number') {
     var doc = obj.ownerDocument || obj.document || obj;
     if (doc != obj) {
       var w = doc.defaultView || doc.parentWindow;
       val = (w != obj);
     }
     else {
       val = (typeof (doc.body) === 'undefined');
     }
  }
  return !val;
}

Can you spot the problem? Yep, the val = (typeof(doc.body)… line is responsible for considering the object a DOM element (remember: section had a property called body and if you look at the code, you’ll see that it ends up messing everything). While the good guys at MS don’t publish a new release which solves this bug, you really shouldn’t use any property named body in an object which is used in a binding relationship (at least, if you intend to serialize that object). Ok, to be fair, you can always use the previous awful hack, but If I were you, I’d renamed the property :)

And that’s it for now. Stay tuned for more.

MS AJAX: bindings and serialization
Wed, Nov 11 2009 19:30

In my “goodbye MS AJAX post”, reader Andy asked a really interesting question: how to serialize an object which is used in a binding relationship? The main problem is that the JavaScriptSerializer doesn’t support circular references. Unfortunately, it doesn’t also provide a way for you to specify which properties should be serialized. However, the problem is still there: how do you serialize the objects used in binding relationships?

I’m still hopping that the team will fix the serializer before MS AJAX RTMs is released, but meanwhile, we’re still left with the problem. I’ve thought a little bit about it and it seems like the best option is to “suspend” the binding, serialize it, and then “resume” it again. Notice that the code you’re about to see has not been tested (it was written during my bus trip home, so it might have one or two bugs :) ). Let’s take a look at the example (I’ve reused most of Andy’s example and I’d like you to concentrate on the save method):

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title></title>
    <script src="Scripts/MicrosoftAjax/start.debug.js" 
        type="text/javascript">
    </script>
    <script type="text/javascript">
        var instance = [
            { title: 'New document',
                content: {
                    sections: [
                        { body: 'Enter text here' },
                        { body: 'other text' }
                    ]
                }
            }
        ];
        Sys.require([Sys.components.dataView],
            function () {
                var view = Sys.create.dataView(
                        "#maincontent",
                        { itemTemplate: '#edit', 
                          data: instance});
        }); 
function onSave(){ var data = Sys.get("$maincontent").get_data(); var backup = {}; function cleanupMetadata(obj, propName, key) { if (obj.hasOwnProperty(propName)) { backup[key] = {}; backup[key][propName] = obj[propName]; delete obj[propName]; } } function restoreMetadata(obj, propName, key) { if (backup[key] !== undefined) { obj[propName] = backup[key][propName]; delete backup[key]; } } for (var i = 0; i < data.length; i++) { var sections = data[i].content.sections; for (var j = 0; j < sections.length; j++) { cleanupMetadata(sections[j], "_msajaxBindings",
i+
"-"+j); } } var serialized =
Sys.Serialization.JavaScriptSerializer.serialize(data);
for (var i = 0; i < data.length; i++) { var sections = data[i].content.sections; for (var j = 0; j < sections.length; j++) { restoreMetadata(
sections[i],
"_msajaxBindings", i + "-" + j); } } alert(serialized); } </script> </head> <body xmlns:sys="BLOCKED SCRIPTSys" xmlns:dataview="BLOCKED SCRIPTSys.UI.DataView"> <div id="edit" class="sys-template"> <label>Title</label> <input sys:value="{binding title}"/> <div sys:attach="dataview" dataview:data="{{ content.sections }}" class="sys-template"> <label>Body</label> <textarea>{binding body}</textarea> </div> </div> <div id="maincontent"></div> <button onclick="onSave()">Save</button> </body> </html>

We’re using two helper methods: cleanupMetadata and restoreMetadata. In the cleanupMetadata, we store the _msajaxBinding info in the backup object. As you can see, we’re building a key by combining the positions of the objects so that we can recover that metadata later. Yes, this isn’t really reusable code and I’d really prefer to have the serializer filter the properties which shouldn’t be serialized. However, this approach will probably be enough for now if you need to serialize an object used in a binding relationship.

And that’s it for now…

The AdoNetDataContext object: what about saving?
Mon, Nov 9 2009 14:34

Well, this really doesn’t deserve any special attention. Ok, let me put it another way: there’s a lot of work going on behind the scenes, but you shouldn’t have to worry with any of it.

I’ve thought about writing a post on the objects that end up being used by the AdoNetDataContext to propagate changes back to the server, but after some thought, I’ve give up on that idea because I’m not seeing anyone use any of these classes directly (yes, the AdoNetDataContext should do it all for you).

And that’s why I’m wrapping up this series on MS AJAX preview 6. I hope you’ve enjoyed it as much as did…Now, I do need to find another topic to keep me busy looking at new stuff…any ideas?

Getting your ADO.NET Data Services uris right: the easy way
Mon, Nov 9 2009 12:13

Here we are again, for more on the MS AJAX library. In the previous post, we’ve seen that we can interact with ADO.NET Data Services by using the AdoNetDataContext instances. Today, we’ll be looking at more advanced features of the ADO.NET Data Services which are also available in the MS AJAX library.

Before going on, I must confess that I’m not really an ADO.NET Data Service user (I guess this has made me curious enough for taking a peek in the future). However, since the MS AJAX library offers such great support for it, I couldn’t resist doing some digging and seeing which options are available for interacting with an existing data service.

According to the docs, ADO.NET Data Services can “be surfaced as a REST-style resource collection that is addressable with URIs and that agents can interact with using standard HTTP verbs such as GET, POST, PUT or DELETE”. In practice, and if we go back to our previous example, we can get all the images by using the uri http://:…/Services/ImageDataService.svc/Images. Besides this simple option, which returns all the images contained in the object, there are still other interesting options. For instance:

  • we can navigate through related properties;
  • we can expand associated properties;
  • we can filter the returned results;
  • we can paginate the returned data.

All these operations are specified through uris. We can easily do them by building the uris by hand. For instance, we can modify the previous example so that it also displays the associated :

<body xmlns:sys="BLOCKED SCRIPTSys"
      xmlns:dv="BLOCKED SCRIPTSys.UI.DataView">
    <div 
      id="myView"
      class="sys-template"
      sys:attach="dv"      
      dv:autofetch="true"
      dv:dataprovider="{{ _ctx }}"
      dv:fetchoperation="Images"
      dv:fetchparameters="{{ {$expand: 'Tags'} }}">
        <h2>{{Name}}</h2>
        <img sys:src="{{Uri}}" sys:alt="{{Name}}" />      
        <div class="sys-template"
            sys:attach="dv"
            dv:data="{{ Tags }}">
            <span>{{Name}}</span>,
        </div>
    </div>
</body>

By using the $expand parameter, we’ll end up getting each image’s associated tags and we can display them by using a nested DataView control. The next image shows what happens when we load the previous page:

expand

We could specify all the “special” parameters this way. However, there is another way: we can rely on the Sys.Data.AdoNetQueryBuilder class for doing building the uri for us.

The AdoNetQueryBuilder’s constructor expects the base uri and exposes several properties which we can use to build the uri which performs a specific operation against the existing ADO.NET Data Service. You’ll probably end up using the ones which are present in the following list:

  • skip and top: we can combine them for paginating data;
  • orderby: used for indicating the sorting order;
  • filter: responsible for filtering the returned data;
  • expand: used for specifying the properties which will be “expanded” and included in the response.

I must confess that I really didn’t find the use of this object intuitive at first. However, after running some experiences, everything started making sense. In order to show you how you might end up using this object, suppose we want to get all the images and associated tags and that we want to order them by name. Here’s a possible solution:

<head runat="server">   
    <style type="text/css">
      .sys-template{
        display: none;
      }      
      img{
        width:320px;
        height:212px;
      }
    </style>
    <script type="text/javascript" 
      src="../Scripts/MicrosoftAjax/start.debug.js">
    </script>
    <script type="text/javascript">
      var _ctx = null;
      Sys.require([Sys.components.adoNetDataContext,
                   Sys.components.dataView],
      function () {
        var uriBuilder = 
new Sys.Data.AdoNetQueryBuilder("Images"); uriBuilder.set_expand("Tags");//$expand uriBuilder.set_orderby("Name");//$orderby _ctx = Sys.create.adoNetDataContext({ serviceUri: "../Services/ImagesDataService.svc" }); Sys.create.dataView( Sys.get("#myView"), { dataProvider: _ctx, autoFetch: true, fetchOperation: uriBuilder.toString() }); }); </script> </head> <body xmlns:sys="BLOCKED SCRIPTSys" xmlns:dv="BLOCKED SCRIPTSys.UI.DataView"> <div id="myView" class="sys-template"> <h2>{{Name}}</h2> <img sys:src="{{Uri}}" sys:alt="{{Name}}" /> <div class="sys-template" sys:attach="dv" dv:data="{{ Tags }}"> <span>{{Name}}</span>, </div> </div> </body>

This time, I’ve opted for using an imperative approach. Things are really similar to what we had before; however, notice that now we’re using an AdoNetQueryBuilder object to set the fetchOperation property of the DataView object.

We start by instantiating the AdoNetQueryBuilder object. If you recall it, I said that this wasn’t really intuitive…it was only looking at the source code that I’ve understood that I was supposed to pass the name of the resource I wanted to access (instead of passing the base uri for the service – not sure on why the constructor’s only parameter is called uri, when resource would have make things so much easier!). Since I was interested in retrieving images, I only had to pass the string “Images” to the constructor.

After having an instance and setting the required properties (recall from above that we wanted to get images+tags and to order everything by name), we can simply call the toString method to get the string which represents the operation we need to perform. And that’s it. We’ll still be speaking about MS AJAX in future posts, so stay tuned for more!

by luisabreu | with no comments
Filed under: ,
Getting started with the AdoNetDataContext
Mon, Nov 9 2009 10:54

Today we’re going to start looking at the AdoNetDataContext. This class expands the DataContext object and uses several specific methods for ensuring the correct interaction with an existing ADO.NET Data Service.

These internal methods added by the AdoNetDataContext are essentially used in identity related operations. In other words, it extends the base DataContext class by introducing several methods which turn on identity support (btw, I’m talking about the stuff we’ve seen in several of the previous posts).

In this post, I’ll be reusing the sample ADO.NET Data Service which is included in MS AJAX preview 6. Here’s the model used internally by the ImageDataService.svc ADO.NET service:

adonetmodel

In this case, and since this is just an intro post, we’ll build a simple page which shows all the images returned by this ADO.NET service:

<head runat="server">   
    <style type="text/css">
      .sys-template{
        display: none;
      }      
      img{
        width:320px;
        height:212px;
      }
    </style>
    <script type="text/javascript" 
      src="../Scripts/MicrosoftAjax/start.debug.js">
    </script>
    <script type="text/javascript">
      var _ctx = null;
      Sys.require([Sys.components.adoNetDataContext, 
                   Sys.components.dataView],
      function () {
        _ctx = Sys.create.adoNetDataContext({
            serviceUri: "../Services/ImagesDataService.svc",
            mergeOption: Sys.Data.MergeOption.appendOnly
        });        
    });
    </script>
</head>
<body xmlns:sys="BLOCKED SCRIPTSys"
      xmlns:dv="BLOCKED SCRIPTSys.UI.DataView">
    <div 
      id="myView"
      class="sys-template"
      sys:attach="dv"      
      dv:autofetch="true"
      dv:dataprovider="{{ _ctx }}"
      dv:fetchoperation="Images">
        <h2>{{Name}}</h2>
        <img sys:src="{{Uri}}" sys:alt="{{Name}}" />      
    </div>
</body>

By now, you shouldn’t really be surprised by anything that is shown in the previous snippet. As you can see, the AdoNetDataContext class protects us from all those nasty details associated with the communication with the ImageDataService.svc server side service. I’m not going to show you how to add, edit or remove items because the samples released with preview 6 already have code which shows how to do those things.

On the next post, we’ll see how to do more interesting operations by using the AdoNetQueryBuilder object. Stay tuned for more on MS AJAX.

More Posts Next page »