April 2007 - Posts

Still related with Silverlight
Mon, Apr 30 2007 22:32

Lutz has released a new version of Reflector with Silverlight support (if you already downloaded a previous version, just run the update checker if you don't get prompted for an automatic update). There's alsoe  monotone demo app for silverlight. Go get it!

by luisabreu | with no comments
Filed under:
SDKs for Silverlight available!
Mon, Apr 30 2007 22:26

What can I say? I should have complained earlier! :)

by luisabreu | with no comments
Filed under:
Silverlight SDKs links broken
Mon, Apr 30 2007 21:15

damn! there goes all the joy!

by luisabreu | with no comments
Filed under:
Silvelight beta is out!
Mon, Apr 30 2007 21:10

According to Mike Harsh, there's a new release with .NET support. It seems like now we've got a new site, new forums and new samples. Everything is concentrated on a single page. It's time to start looking at Silverlight!

by luisabreu | with no comments
Filed under:
Silverlight: simplifying the FilmStrip sample
Mon, Apr 30 2007 13:36

Today I've started looking at the samples that accompany Silverlight. I started with the FilmStrip sample. After looking at it for some minutes, I thought that maybe I could simplify the code needed to achieve the image transitions. If you look at the original code, you'll see that there are several storyboards that set up each transition. you'll also see that they're really duplicates and that the only thing that changes is the value of the Value property applied to the SplineDoubleKeyFrame element. In fact, if you pay attention to the storyboards, you'll see that each storyboard decreases (or increases, depending on the direction you follow :) ) the value by 1024.

So, what's happening here is that these extra lines of XAML (for each transition) could be reduced to one storyboard whose value is changed during the click of the next/previous button. To achieve this, you should start by removing all the extra storyboards and kepp only one. In my case, I've ended up with this xaml (i'm only putting the inner loadedRoot canva's triggers xaml):

<Canvas.Triggers>
 <EventTrigger RoutedEvent="Canvas.Loaded">
  <EventTrigger.Actions>
    <BeginStoryboard>
       <Storyboard BeginTime="5" Duration="00:00:01" x:Name="story">
             <DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetProperty="X"  Storyboard.TargetName="slideX1">
                <SplineDoubleKeyFrame
                       Name="anim1"
                       KeySpline="0.7,0,0.4,1" Value="0" KeyTime="00:00:00.8"/>
           </DoubleAnimationUsingKeyFrames>
          <DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetProperty="X" Storyboard.TargetName="slideX2">
                <SplineDoubleKeyFrame
                     Name="anim2"
                     KeySpline="0.7,0,0.4,1" Value="1024" KeyTime="00:00:00.8"/>
           </DoubleAnimationUsingKeyFrames>
          <DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetProperty="X" Storyboard.TargetName="slideX3">
                <SplineDoubleKeyFrame
                    Name="anim3"
                    KeySpline="0.7,0,0.4,1" Value="2048" KeyTime="00:00:00.8"/>
         </DoubleAnimationUsingKeyFrames>
         <DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetProperty="X" Storyboard.TargetName="slideX4">
              <SplineDoubleKeyFrame
                  Name="anim4" 
                  KeySpline="0.7,0,0.4,1" Value="3072" KeyTime="00:00:00.8"/>
         </DoubleAnimationUsingKeyFrames>
         <DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetProperty="X" Storyboard.TargetName="slideX5">
             <SplineDoubleKeyFrame
                Name="anim5"
                KeySpline="0.7,0,0.4,1" Value="4096" KeyTime="00:00:00.8"/>
       </DoubleAnimationUsingKeyFrames>
       <DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetProperty="X" Storyboard.TargetName="slideX6">
          <SplineDoubleKeyFrame
              Name="anim6"
              KeySpline="0.7,0,0.4,1" Value="5120" KeyTime="00:00:00.8"/>
       </DoubleAnimationUsingKeyFrames>
      <DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetProperty="X" Storyboard.TargetName="slideX7">
         <SplineDoubleKeyFrame
             Name="anim7" 
              KeySpline="0.7,0,0.4,1" Value="6144" KeyTime="00:00:00.8"/>
      </DoubleAnimationUsingKeyFrames>
      <DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetProperty="X" Storyboard.TargetName="slideX8">
          <SplineDoubleKeyFrame
               Name="anim8" 
               KeySpline="0.7,0,0.4,1" Value="7168" KeyTime="00:00:00.8"/>
       </DoubleAnimationUsingKeyFrames>
     </Storyboard>
    </BeginStoryboard>
  </EventTrigger.Actions>
 </EventTrigger>
</Canvas.Triggers>

As you can see, I've changed the name of the storyboard to story and I've named each of the SplineDoubleKeyFrame so that we can change its Value during each button click. As I've said, in the initial sample each storyboard would be an exact copy of the previous: the only thing that changes is the value of Value property (and this value is decremented by 1024 in each element). With this knowledge, we just need to build a function that increments or decrements each of the animation by the necessary factor:

function updateAnims( factor ){
   for( var i = 1; i < 9; i++ ){
        wpfe.findName( "anim" + i ).Value = wpfe.findName( "anim" + i ).Value - factor;
   }
}

Changing the upForward method to use the new strategy is really simple:

function upForward (s,e) {
  if (currentSlide < 8) {
     currentSlide++;
     var factor = 1024;
     updateAnims( factor );
     wpfe.findName("story").Begin();
     if (currentSlide < 8) {
        wpfe.findName("forwardButton").fill = "#FF000000"
        wpfe.findName("forwardButton").stroke = "#FFAAAAAA"
    }
    else {
        wpfe.findName("forwardButton").fill = "#FF000000"
        wpfe.findName("forwardButton").stroke = "#FF222222"
    }
  }
  wpfe.findName("backButton").fill = "#FF000000"
  wpfe.findName("backButton").stroke = "#FFAAAAAA"
}

All that is needed is to update the animations before running them (this is only possible because the animation retains its final value after beeing run). You'll also need to change the upBack method so that it updates the animation values with negative values:

//....previous code removed
currentSlide--;
var factor = 1024;
updateAnims( -factor );

wpfe.findName("story").begin();

While performing these changes, I've also noticed that each image is downloaded through its own Downloader object, which also seemed a waste of resources. After looking at the docs, it seemed like I couldn't use only one downloader for all the images because loading ad image could only be done by setting a path or associating a Downloader with it. I though that if I associated a downloader with an Image and then downloaded a second image with the same downloader, that isecond mage would be rendered in the associated Image control (ie, i thought that callluing the SetSource method would result in creating a binding between the Image and the Downloader). Since I didn't find any way to explicitly set the bytes of the image, I thought that those extra-Downloader objects were really necessary. Even though it seemed like I was wasting time, I've changed the code so that it only used one downloader. The first thing I did was create a global method with the following code:

function __getDownloader(){
  if( downloader == null ){
      downloader = wpfe.createObject("Downloader");
      downloader.downloadProgressChanged = "BLOCKED SCRIPTdownloadProgressChanged"
      downloader.completed = "BLOCKED SCRIPTdownloadCompleted"
  }
  return downloader;
}

And the, I've replaced these lines (in the downloadAssets and downloadCompleted methods):

downloader = wpfe.createObject("Downloader");
downloader.downloadProgressChanged = "BLOCKED SCRIPTdownloadProgressChanged"
downloader.completed = "BLOCKED SCRIPTdownloadCompleted";

with this one:

downloader = __getDownloader();

After opening the page in the browser, I though that I'd get the last picture eight times. But that didn't happen...it worked, ie, using a single Downloader was more than enough to get all the images...So, it seemed like this sample was a little "bloated" after all...

by luisabreu | with no comments
Filed under:
Strangest Vista bug?
Sun, Apr 29 2007 23:11

Michael Howard describes what a strange vista bug :)

by luisabreu | with no comments
Filed under:
Building controls for Silverlight
Sun, Apr 29 2007 23:03

I decided spending 1 or 2 hours looking at how we could build and encapsulate controls with Silverlight and Javascript (nothing too fancy). It was a great exercise since it helped  me understand a little more about the limitations of the current version of Silverlight. Unfortunately, 1 or 2 hours weren't enough to build a really cool framework. However, it was more than sufficient to get a small proof of concept showing that it is possible to build a framework where you have Javascript classes that are capable of injecting xaml and intercepting the events generated by those elements. When I started thinking about this, I had the following objectives:

  • the controls should be able to inject XAML into a Canvas (or another) object specified as its parent element;
  • the controls should encapsulate all the logic for making its transition beween states (this means that it should handle mouse enter/leave events, etc);
  • the controls should fire events that can be handled by the page programmer;
  • I wanted to reuse ASP.NET AJAX  for getting OO goodies.

If you take some time to look at the code, you'll notice several things:

  • I've only built a control (a button) base on the button code written by Bryant Likes. I'm not a designer, so I really don't have the skills to reproduce the looks of the remaining standard controls :(;
  • I've built a base class that is responsible for getting the XAML and inserting it into the parent canvas.
  • Each derived class should override the method that generates XAML
  • There are 2 methods which are called in important times on  the lifetime of the created objects (_internalHierarchyCreated is called after the createFromXaml method has been called and _internalHierarchyAddedToControl is called after the controls have been added to the child collection of the parent element)
  • You can see that I change the text shown by the textbox of one of the buttons before adding it to the control hierarchy and that's where I set up the event handlers(take a peek at the _internalHierachyCreated method)
  • There's a global class that is responsible for mapping each event on a specific method of the instance responsible for that event. Each control must register himself with the class to handle the necessary events for it to work properly. When I build this class, the idea was to hook up the events directly with the "static" methods. Unfortunately, Silverlight can only handle simple method names (ie, if you to set up an event with BLOCKED SCRIPTLA.Silverlight.SilverlightEventManager.dispatchLeftMouseDownEvent, it simply won't call that method - that's why i created the top __XXX methods).

Now that I've ended my available time for playing with Silverlight controls, i think that my architecture could have been improved a lot (in fact, now that I've finished, i really think that it kind of sucks :)). Here are some of the things I'd do if I could start over:

  • I'd create the classes as controls (instead of simple classes);
  • I'd create a canvas element that would be usable as top control;
  • I'd probably think hard to get a list of "XAML" elements that would be wrapped by Javascript classes;
  • I'd simplify event handling code. The current demo has lots  of code that could be simplified (for instance, instead of performing a pre-registration of the control with the global SilverlightEventManager object, i'd refactor that class so that it would perform event registration in  a single step);
  • I'd add xml-script support for these elements.

As a final note, I really hope that this code is obsolete by tomorrow (or by the end of MIX). If that doesn't happen, then we'll have lots and lots of work trying to build WPF/e controls...

by luisabreu | 4 comment(s)
Filed under:
Silverlight: events are string properties...
Fri, Apr 27 2007 10:57

This is bad...almost as bad as not giving us controls. that's all I have to say right now...

by luisabreu | with no comments
Filed under:
Silverlight: no mouse down event?
Fri, Apr 27 2007 6:16

After looking at the current Silverlight docs and after seeing this post in the forums, it seems like you can only detect left clicks on items. In other words, there is only a MouseLeftButtonDown/Up event and no corresponding RightLeftButtonDown/Up event. I thought: well, there surelly is a MouseDown event which precedes the MouseLeftButtonDown event, but guess what: there isn't!

My explanation on why this happens: the last time I've looked MACs' mouse only had one button :) (yeah, I couldn't resist making a silly joke about macs...sorry about that:))

by luisabreu | with no comments
Filed under:
Silverlight: why do we havetriggers? or, why do we have them and they simply refuse to work?
Thu, Apr 26 2007 12:19

After installing the Silverlight templates, I've started learning it by trying to build a new button control (the choice may seem strange, but currently Silverlight doesn't have any controls). Well, if you create a new project based on the template, you'll see that it already has code that reproduces the basic behavior of a button. After looking at the code, I thought that most of the button's behavior could be built directly from XAML (at least, that's what i thought then). Let me explain this a little better: the default code generated by the project template has javascript code for handling the mouse enter/leave events which changes the offset of a linear gradient brush that is applied to fill the interior of the rectangle. Oh these MS guys...why, oh why did they write that js code when you have routed events and triggers??? So, with this basic WPF knowledge, I decided to remove the js references and add two triggers: onde for the Rectangle.MouseEnter event and another  for the Rectangle.MouseLeave event. Each has its own storyboard, where a single DoubleAnimation refreshes the Offset values of one of the gradients (ie, it simply mimics the js default code, but it uses animations inside storyboards which respond to events -or, at least that's what i thought it would do).

guess what: it simply didn't work. I tried replacing the events for mouse down/up and again it didn't work. In fact, i simply couldn't see anything! It was only when i changed the duration of the animation  that i was able to see what's going on: the animations were being run in sequence, during the loading of the controls! Yes, that's right: even though I've set the events to enter/leave and mouse up/down, the damn thing only worked during the loaded event (at least, that's what it seemed)...

After reading the docs, I've finally found something similar here. I've copied/pasted it and guess what? It doesn't work! Interestingly, if you adapt it and put it in xaml pad, it works as expected (so does my initial button code)

Now, the big question: why doesn't it work? aren't we suppose to have routed events? or am I doing something wrong?

anyone?

thanks!

by luisabreu | 5 comment(s)
Filed under:
Book review: WPF Unleashed
Wed, Apr 25 2007 12:35

Yesterday I've finished reading Adam Nathan's WPF Unleashed. What can I say that Jeff hasn't already said?

by luisabreu | with no comments
Filed under:
Improving your animations with the tookit animation framework - part II
Mon, Apr 23 2007 15:28

Today we're talking about the  FadeAnimation class. As I've said in the last post, the Animation class is abstract and is extended by several animations introduced by the toolkit. The FadeAnimation class is really simple: it lets you apply fade to an HTML control present on the page. The FadeEffect enumeration introduces 2 values which are used to give you a fade in (FadeIn) or a fade out (FadeOut) effect. As  you might expect, you can set all these properties (and the ones inherited from the base Animation class) through a constructor. Here's a simple example which shows how to create a fade out effect over a div:

<!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>
        <title>Untitled Page</title>
        <script type="text/javascript" src="MicrosoftAjax.debug.js">
        </script> 
        <script type="text/javascript" src="timer.js">
        </script>
<script type="text/javascript">
   var animation = null;
   function handleClick(){
        if( animation == null ){
             animation = new $AA.FadeAnimation( $get("target"), //target of animation
                                   3, //duration in seconds
                                   25, //number of frames per second
                                   $AA.FadeEffect.FadeOut, //fade effect
                                   0, //minimum opacity
                                  1, //maximum opacity
                                  Sys.Browser.InternetExplorer == Sys.Browser.agent );//force layout: should be true in IE!
    }
    animation.play();
   }
   </script>
  </head>
 <body>
    <script type="text/javascript" src="common.js">
    </script>
    <script type="text/javascript" src="animations.js">
     </script>
     <div id="target" style="background-color: gray">This is a simple div</div>
     <input type="button" value="start animation" onclick="handleClick()" />
 </body>
</html>

After loading the dependencies correctly (don't forget what I've said here about the client files of the toolkit!),  getting a fade out is easy: just create the animation and call its play method. As I've said in the last post, Animation is a component. That is why it's a good idea to call the dispose method when you're done with the animation (in this case, handling the unload event would be perfect to do that!). Since I'm talking about good practices and recommendations, you should also keep in mind that handling events with the onXXX attribute isn't really a good thing: a better option would be to set it up in code, and since you're already including the base AJAX file, you should use the event helpers to do that and get automatic browser  compatibility.

oh, another note: the $AA var is introduced by the tookit files and you can think of it as a  formnemonic AjaxControlToolkit.Animation namespace.

Besides this class, the toolkit animation framework adds 2 other fade classes: FadeInAnimation and FadeOutAnimation. As you can see (if you open the animations.js file), they're only shortcuts to let you create fade in and fade out animations (though I'm not convinced if the extra lines needed for introducing these new classes is a good design call - think: adding $AA.FadeEffect.FadeOut to the constructor of the FadeAnimation class results in adding only a few chars; creating the classes add a few lines to the file...).

And that's all for today. In the next post, I'll continue presenting the toolkit aimation framework.

by luisabreu | with no comments
Filed under: ,
ASP.NET AJAX: WCF support??
Mon, Apr 23 2007 8:24

One of the things that was removed from the final versions of ASP.NET AJAX was WCF web service support. Does anyone know if we'll be having it on orcas? I'm asking because I've just started looking at Silverlight and there really isn't any support for it there (as i was expecting)...

by luisabreu | 5 comment(s)
Filed under: ,
ASP.NET AJAX: creating a trigger on a client control
Sun, Apr 22 2007 14:25

A few months ago, I've written a post on a forum which shows how to trigger a conditional postback from an HTML client control. Today I was asked about it again. It's not really complicated after you understand that triggers are maintained in a javascript array by the client PageRequestManager object. When there's a postback, the PageRequestManager checks that array and if the control responsible for the postback is on that list, you'll get a partial postback (in fact, there are much more things done by the PageRequestManager, but none is important for this example). The rest of the "normal" behavior associated with triggers is accomplished by server side code.

Here's an example that shows how you can create a "virtual" trigger on a client HTML input:

<%@ Page Language="C#" AutoEventWireup="true"  %>
   <script runat="server">
       protected override void OnLoad(EventArgs e)
       {
           base.OnLoad(e);
           if (ScriptManager1.IsInAsyncPostBack &&
               Request.Params["__EVENTTARGET"] == "txt")
           {
               panel.Update();
           }
       }
   </script>
   <!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>Untitled Page</title>
   <script>
   function main()
   {
       // Add Client Code here
   }
   </script>
   </head>
   <body>
       <form id="form1" runat="server">
           <asp:ScriptManager ID="ScriptManager1" runat="server">
           </asp:ScriptManager>
           <asp:updatepanel runat="server" id="panel" UpdateMode="Conditional">
            <ContentTemplate>
                panel 1:
                <%= DateTime.Now.ToString() %>
            </ContentTemplate>
           </asp:updatepanel>
           <asp:updatepanel runat="server" id="Updatepanel1" UpdateMode="Conditional">
            <ContentTemplate>
                panel 2:
                <%= DateTime.Now.ToString() %>
            </ContentTemplate>
           </asp:updatepanel>
           <input type="text"  id="txt" onchange="__doPostBack('txt','');"; />
       </form>
       <script type="text/javascript">
        Sys.WebForms.PageRequestManager.getInstance().add_pageLoaded( function() {
            Sys.WebForms.PageRequestManager.getInstance()._asyncPostBackControlClientIDs.push( "txt" );} );
       </script>   
   </body>
   </html>

During the load event, we add a reference to the textbox on the _asyncPostBackControlClientIDs array. We also configure the textbox so that when its content changes, we initiate a postback. This is all that is required for getting a partial postback from an HTML control placed outside an UpdatePanel.

In this case, the example also shows how to refresh a panel when the postback is caused by our HTML textbox control: we check the Params collection and see if the __EVENTTARGET is txt (which is the id of the texbox). And that's it. simple, right?

by luisabreu | 3 comment(s)
Filed under: ,
Rss feed problems
Sat, Apr 21 2007 15:59

My good friend Paulo has alerted me for some problems related with the feedburner feed I've created. Unfortunately, I've put the wrong url. This is the correct one: http://feeds.feedburner.com/Laneten

Sorry for the mess.

by luisabreu | with no comments
Filed under:
Improving your animations with the Toolkit animation framework - part I
Fri, Apr 20 2007 18:46

The Ajax Control Toolkit introduces several classes and helpers which makes adding animations to an object really easy. Today I'm starting a new serious of posts where I'll describe the main client classes introduced by the toolkits. If you already know the client classes introduced by the preview bits, you'll be pleased to know that the animation framework presented in the toolkit are (really!) much much better than those found in the preview bits. Besides the animation classes, the framework introduces some utility methods and some behaviors.

Today I'm talking about the base (and abstract) Animation class which can be found on the AjaxControlToolkit.Animation namespace. This is the ultimate base class from which all the other animations must inherit (as a side note, keep in mind that animations are components, ie, they inherit from the Component class defined by the AJAX client library). Currently, the Animation class exposes several properties which let you:

  • set the length of the animation in seconds (duration property);
  • define the number of steps per second (fps property);
  • identify the HTML control you're animating (target property. If you're using an ID, then you need to use the animationTarget property - which is a write only property);
  • check if the animation is playing (isPlaying) or if it's active (isActive);
  • get the current completed percentage of the animation.

Besides these "traditional" properties (which already existed on the preview bits Animation class), the class adds a new interesting property: DynamicProperties. This property can be seen as a dictionary which lets you associate a javascript expression to an animation property. Why would you want to do that? well, the great thing about this dictionary is that all the expressions contained on it are executed before the animation is played (which is really useful when you want that one of the properties gets its value from some method or some object that exists in the page).

As you might expect, the class introduces some methods that let you play, pause and stop an animation. You start (or resume) an animation by calling the play method. Internally, this method will create a new Sys.Timer instance (if needed) used to increment the animated value of the target object and it'll fire the start event. Then, the animation tries to run all the javascript expressions you've set on the DynamicProperties (note that this won't happen after a pause, ie, the DynamicProperties will only be set if you're calling play for the first time or if you're calling it after the animation has stopped).

Before returning, the play method sets the interval of the timer (which takes into account the fps property to determine the interval used for firing the timer's tick event) and updates the completed percentage of the animation. When a tick occurs, the animation calls the onStep method, passing it the current completed percentage of the animation. Internaly, the method simply calls 2 methods (which are abstract and should be overriden by all the derived animations): setValue and getAnimatedValue.

getAnimatedValue should return the "current" state of the animation based on the completed percentage (as you'll see in the next posts, this value depends on the type of animation you're using). setValue is responsible for receiving the value returned by the getAnimatedValue and applying it correctly to the target of the animation. If you're thinking about creating your own animations, you must override these methods.

Pausing the animation is accomplished through the  pause method: it simply disables the timer and raises the propertyChanged event. Stopping a running animation envolves killing the timer (ie, calling its dispose method), setting the completed percentage to 100 and firing the end event.

Besides these "public methods", the class also contains some utility methods. For instance, the interpolate method calculates the appropriate value between a starting and ending values, taking the current percentage into account.

And that's all for today. I do really think that getting these basic aspects is essential for understanding how animations work. Cya in the next post.

by luisabreu | with no comments
Filed under: ,
Mike Taulty on LINQ
Fri, Apr 20 2007 13:31

Mike Taulty has produced some cool videos on LINQ. here's the current list:

  1. Introduction to LINQ to SQL
  2. A tour around the data context
  3. Mapping .NET types to relational schema
  4. Tools for generating mapping information
  5. Inserting Data

Keep them coming please!

by luisabreu | with no comments
Filed under:
VS Orcas beta 1 is out
Fri, Apr 20 2007 13:22

More info here.

by luisabreu | with no comments
Filed under:
Book review: Applications = Code + Markup
Mon, Apr 16 2007 16:33

This is the last book written by Charles Petzold. Before proceeding, let me assure you one thing: Petzold is good, real good. No doubt about it. Now, the book review...well, I'm disapointed with it. I've been following Petzold's work for a long  time. I've read at least 4 books written by him, so you can say that I've enjoyed his previous work. However, I don't like this book. And why don't I like it? well, for starters, it's a bit boring. Too many words to explain WPF's concepts, no cool graphics showing the results of the demo apps (which is really weird on a WPF book) and...too many guessings! What do I mean with "too many guessings"? well, there are several places where the author tries to guess how something (in WPF) is implemented or  gives his opinion on how he would do it. I'm not sure about you, but when I need to check the internals, i just open Reflector and see how it's done. After all, we're in 2007, right?

Would I recommend this book? hum...I'm sorry, but the answer is no. I'm giving it 5/10 because it's a Petzold book (if I had read it without knowing the author's name, i wouldn't have been so "nice").

by luisabreu | with no comments
Filed under:
Book Review: C++\CLI The Visual C++ Language for NET
Mon, Apr 16 2007 16:20

This book is what you want if you're after a book that will get you up to speed in C++\CLI. Even though I haven't done any programming in C++ for (at least) 4 years, I was able to follow the book without any problems. The only thing that could be improved was the chapter on interop: nothing would be lost if it had a couple more pages :) . Id' give it 7/10.

by luisabreu | with no comments
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