Silverlight to Angular – 5 (IValueConverter – filter)

IValueConverter is without doubt one of the most used feature (at least in our side of the world) in Silverlight. We have lot of data, which, if we show them as it is to the user, it is completely useless. To make it more meaningful, we use Value Converter to convert and display it to the user. IValueConvert provides a way to add logic to the binding data without changing the data. IValueConverter has two methods, ‘Convert’ to convert the original data that is bound but translate with some logic to give different result that then get rendered in the UI. ‘ConvertBack’ is to take user input and apply some logic to revert it to some other form to store it at the back end. Most of the time, whenever we use IValueConverter, we always end up using the ‘Convert’ and seldom use ‘ConvertBack’, now I am going to use that as an excuse since Angular provides only one way convert, it does not have provision to convert it back. Even though I say, we don’t use ‘convertback’ but it is very useful feature and is used a lot, one good example is ‘Color Picker’. We will try to explore convert back at a later time. For now, we will see what is available in Angular out of the box that we can use.

Problem: Multiply two numbers and display the result with two decimal points.

Silverlight:

Only difference between our previous solution to this is that we have value converter and it is used in the binding to change the incoming data to more meaningful data. Lets look at the view

View:

1 <Grid.Resources> 2 <converter:TwoDigitConverter x:Key="Converter" /> 3 </Grid.Resources> 4 <TextBlock>Number 1</TextBlock> 5 <TextBox Text="{Binding NumberOne, Mode=TwoWay}" Grid.Column="1"></TextBox> 6 <TextBlock Grid.Row="1">Number 2</TextBlock> 7 <TextBox Text="{Binding NumberTwo, Mode=TwoWay}" Grid.Row="1" Grid.Column="1"></TextBox> 8 <Button Grid.Row="1" Grid.Column="2" Command="{Binding Multiply}" CommandParameter="">Multiply</Button> 9 <TextBlock Grid.Row="2" Grid.Column="1" Text="{Binding Total, Converter={StaticResource Converter}}"></TextBlock>

Line (2 – 4) provides us the hook into the value converter to be used in the XAML. Line (9) binds the result, even though the it binds to the result, we are asking the binding to use the associated converter to apply the conversion based on the convert logic and use the result to display in the ‘TextBlock’.

ValueConverter:

1 public class TwoDigitConverter:IValueConverter 2 { 3 4 public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) 5 { 6 var result = value as float?; 7 result = result ?? 0; 8 return string.Format("{0:N2}", result); 9 } 10 11 public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) 12 { 13 throw new NotImplementedException(); 14 } 15 }

When we create Value Converter, it has to implement IValueConverter, which have only two methods that we need to implement. Convert and ConvertBack as we discussed in the beginning. Since Angular only supports one way conversion, we created this sample conveniently to show case only the ‘Convert’ part of ValueConverter.  Convert method does not do anything special, it takes the input number and returns the result with 2 decimal digits.

Our view model exposes the three variables and a command, nothing else.

Angular:

Angular provides filters, a way to format data for display. There are couple of ways we can use filters. You can use filters in line or create custom filters. If you were to create custom filters, you can reuse them in any controllers in a given module, it is like using resource file in Silverlight. One additional benefit of the creating custom filters, you can chain them to pass the input to multiple functions before creating final result. Lets first look at the inline approach to solve the problem and then we will write custom filter.

In-Line formatting:

View:

Since it is inline formatting, the formatting happens in the View code itself.

1 <!DOCTYPE html> 2 <html ng-app> 3 <head> 4 <title></title> 5 <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.0.1/angular.min.js"></script> 6 <script src="scripts/controller.js"></script> 7 </head> 8 <body> 9 <div ng-controller="controller"> 10 First Number: <input ng-model="NumberOne"/><br/> 11 Second Number: <input ng-model="NumberTwo"/><button ng-click="Multiply()">Multiply</button><br/> 12 Result : {{Result | number:2}} 13 </div> 14 </body> 15 </html>

Everything is standard here except line (12). In line 12, we get the result from the controller and angular will read the result and feed it to the expression in the pipe. In this case we are using number filter out of box to format number. There are few filters available out of box,  take a look at this AngularJS cheat sheet.

Custom formatting:

There are situations, where out of the box filters will not be sufficient and we will need some custom filters to format the data. Angular filters are very powerful on that regard. As I said previously,

  1. Since you can create filters as part of module, these filters are available across all the controllers in the module.
  2. Filters can be chained to create more customizable output data.
  3. Compare to Silverlight, we can pass in as many parameters as you want to the filters.
  4. If the filters are very simple and out of box, use the default filters.
  5. It written properly, you can call filters with only available arguments and rest can assume default values(like optional parameters in c#).

So in our case, even though we could use simple out of the box formatting, we will create a custom filter just for the sake of demonstration. So far in all our examples we left ng-app as empty string but when you want to use filters then you need to create a module and assign the filter to that module. With that in mind, here is the modified view.

1 <!DOCTYPE html> 2 <html ng-app='customFilters'> 3 <head> 4 <title></title> 5 </head> 6 <body> 7 <div ng-controller="controller"> 8 First Number: <input ng-model="NumberOne"/><br/> 9 Second Number: <input ng-model="NumberTwo"/><button ng-click="Multiply()">Multiply</button><br/> 10 Result : {{Result | twoDigits}} 11 </div> 12 <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.0.1/angular.min.js"></script> 13 <script src="scripts/controller.js"></script> 14 </body> 15 </html>

Line (2) now has the module name. We named it as ‘customFilters’. You will see in the view model, how we create a module and add the filters into the module.

**Note: It important that you put the module name in ng-app, if not none of the custom filters you write will work. Take it from me, I spend hours trying to figure out why my custom filter was not working, finally to find out, I missed the module name in the ng-app. **

Line (10) now feeds the result value to the custom filter ‘twoDigits’, which will do the magic of converting the result to a number with two decimal digits.

Controller:

1 angular.module('customFilters', []). 2 filter('twoDigits', function() { 3 return function(input) { 4 return input.toFixed(2); 5 }; 6 }); 7 8 function controller($scope) { 9 $scope.NumberOne = 0; 10 $scope.NumberTwo = 0; 11 $scope.Result = 0; 12 $scope.Multiply = function () { 13 $scope.Result = $scope.NumberOne * $scope.NumberTwo; 14 }; 15 }

So what is new compare to what we have seen so far?  Line (1-6) creates the module and adds the custom filter to the module.

Line (1) – creates the module named ‘customFilters’. During the angular context generation, angular get hold of ng-app for the first time, it will look for the definition of module in the controller to bootstraps the application. In the module definition, there are two parameters, first one is the name of the module and for sake of simplicity, lets ignore the second parameter ‘[]’ for now.

Line (2) – Please note that, there is a ‘.’ at the end of the line (1), with that we are directly adding a filter called ‘twoDigits’ to the filter factory.

Line (3) – Actual function which takes input and perform some task, in here format number to two decimal digits (line 4) and return the result.

Even though I presented ‘filters’ as way to format data, it is much more than that, it can do what ‘filter’ is supposed to do like filtering. We will look at that in one of the later post. Lets take this example one more level up to show how to pass parameters to the filter.

Problem: Two two number and multiple and set the result precession based on user input.

View:

The view is exactly same as the last one except now, we have one input field to enter number of decimal digits user wants to see in the result.

1 <div ng:app="customFilters"> 2 <div ng-controller="filterCntl"> 3 First Number: <input ng-model='NumberOne'></input><br> 4 Second Number: <input ng-model='NumberTwo'></input><button ng-click='Multiply()'>Multiply</button> 5 Decimals : <input ng-model='Decimals'></input><br> 6 Result: {{ Result | twoDigits: Decimals }} 7 </div> 8 </div>

The interesting part in the view is Line (6), this time, instead of feeding result to twoDigit filter, we are also passing the Decimals value as parameter to the filter.

Controller:

1 angular.module('customFilters', []). 2 filter('twoDigits', function() { 3 return function(input, decimals) { 4 return input.toFixed(decimals); 5 }; 6 }); 7 function filterCntl($scope) { 8 $scope.NumberOne = 0; 9 $scope.NumberTwo = 0; 10 $scope.Result = 0; 11 $scope.Decimals = 2; 12 $scope.Multiply = function () { 13 $scope.Result = $scope.NumberOne * $scope.NumberTwo; 14 }; 15 }

Line (3) of the controller now takes two parameters, first argument will always be the input and second one is number of digits. For sake of simplicity I am not checking isNaN etc., in the ‘twoDigits’ method. Here is the jsFiddle of the solution.

Suppose you may want to pass more than one argument to the filter function, then you will simple concatenate the arguments as

{{ input | filter: arg1 : arg2 : arg2}} 

I found filter to be very powerful and useful.

Advertisements

Silverlight to Angular – 4 (DataTemplates)

In Silverlight, when you are rendering some complicated data in a control, you will use DataTemplate to make it more readable to the user. One simple example would be, if you have a ListBox and you normally put a single property like state or year etc.,. But you will run into a situation, where you may want to display more than one property per row. One such example is displaying Diggs story to demonstrate the use of Listbox in Silverlight. For sake of simplicity, we will look a very simple example.

Problem: Display all students with their ID and Name in a listbox to select.

Silverlight:

By default, when you use ListBox in silverlight, you can bind it to a collection and point to a property of the object in the collection to display. If you want to display more than one properties from the object, then you need to use ItemTemplate. That is what we are going to do. For this example, we have a collection of Students, with following properties

1 public class Student 2 { 3 public string Id { get; set; } 4 public string Name { get; set; } 5 public string Grade { get; set; } 6 }

Since we need to work with collection to bind to control’s itemsource, we will create an observable collection of students like the following

1 public class Students:ObservableCollection<Student> 2 { 3 public Students() 4 { 5 Add(new Student() {Id = "1", Name = "First", Grade = "A"}); 6 Add(new Student() {Id = "2", Name = "Second", Grade = "B" }); 7 Add(new Student() { Id = "3", Name = "Third", Grade = "C" }); 8 9 } 10 }

View:

In our View, we will create a Listbox control and bind the Students collection to it. We are planning to display for now, just the Id and Name. Since the control’s DisplayMembersPath limitation, we will create a ItemTemplate to host the data template.

1 <ListBox ItemsSource="{Binding CurrentStudents}" Grid.Column="1" Margin="36,5,36,10"> 2 <ListBox.ItemTemplate> 3 <DataTemplate> 4 <Grid> 5 <Grid.ColumnDefinitions> 6 <ColumnDefinition Width="20*"></ColumnDefinition> 7 <ColumnDefinition Width="*"></ColumnDefinition> 8 </Grid.ColumnDefinitions> 9 <TextBlock Text="{Binding Id}" Grid.Column="0"></TextBlock> 10 <TextBlock Text="{Binding Name}" Grid.Column="1"></TextBlock> 11 </Grid> 12 </DataTemplate> 13 </ListBox.ItemTemplate> 14 </ListBox>

Nothing special here, We assigned the ObservableCollection of Students to the ListBox, and then we create a gird inside each row of ListBox and display Id and Name.

ViewModel:

This exposes a property for CurrentStudents, nothing else

1 public ObservableCollection<Student> CurrentStudents 2 { 3 get 4 { 5 return new Students(); 6 } 7 }

Most of the work we need to do is in the View to tell the Silverlight to create each row of ListBox with more than one property of the object collection.

AngularJS:

To my surprise, the amount of code we need to write to achieve the same is very less in Angular, there is not a lot of ceremony in here. The only and the main difference here between Silverlight and Angular is the building elements for the collection. In Silverlight we just pass the collection information and property to use in XAML and Silverlight takes care of traversing through the collection and building each row and putting the values property. Angular behaves same way except except instead of just pointing to the collection as itemssource, in angular, you will write the ‘foreach item in collection’ in the element instead of just the collection. Other than that everything from programming side is same. With that lets look at the view. The main difference is in the view, so lets make sure we understand it.

1 <!DOCTYPE html> 2 <html ng-app> 3 <head> 4 <title></title> 5 </head> 6 <body> 7 <div ng-controller="TemplateCtrl"> 8 <select ng-model="SelectedItem"> 9 <option ng-repeat="student in Students"> 10 {{student.Id}}-{{student.Name}} 11 </option> 12 </select> 13 </div> 14 <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.0.1/angular.min.js"></script> 15 <script src="Scripts/TemplateCtrl.js"></script> 16 </body> 17 </html>

If you are following my previous blogs, you should be ok till line (8). Line (8) specifies that you are creating a list box (HTML – Select) and ignore the rest in line(8) for now. Line (9) – (11) specifies, what are the things goes into each and every options.

<option ng-repeat="student in Students">

In line (9) there is a new directive that we haven’t used before. ng-repeat, tells angular to create individual element for each and every object in a collection. In this example, angular will create individual option element for every object in ‘Students’ collection based on the template specified in line (10). So if we are going by the collection we created in the Silverlight view model, there are 3 students which means, Angular will create 3 option elements. Line (10) is a simple template, which does nothing but a simple one way binding of Id and Name properties of student class.

ViewModel:

As you can expect, most of the work is in the View since template work is UI related and ViewModel does not have any idea about templates. So our view model looks like the following

1 function TemplateCtrl($scope) { 2 $scope.Students = [ 3 { Id: "1", Name: "First", Grade: "A" }, 4 { Id: "2", Name: "Second", Grade: "B" }, 5 {Id: "3", Name: "Third", Grade: "C"}]; 6 }

I skipped ‘SlectedItem’ on purpose for now.

Silverlight to Angular – 3 (Commands)

In Silverlight, we use Commands to do clean separation of View and ViewModel. If we were not using commanding, we will end up creating code behind code to handle the events fired by the controls and then publish the message from view to viewmodel or call viewmodel method from view. Either way, there is unnecessary code in code behind. With command, we can bind the command to a control event using magic black box (in my case Jounce or your ICommand implementation) which will take care of the wiring control event directly to viewmodel method, leaving our code very clean.

We will reuse the code we did in the last blog since it already has commanding implementation. If you want to know more about how to do commanding, please take a look at the Jounce Command documentation or one of my old blog on commanding.

Problem: Display number of times a button is clicked.

I am not going to explain the Silverlight solution here since it is already explained here. Let’s look at the AngularJS solution here since I conveniently skipped it in the previous blog.

View:

1 <!DOCTYPE html> 2 <html ng-app> 3 <head> 4 <title></title> 5 </head> 6 <body> 7 <div ng-controller="Controller"> 8 Number of Clicks:{{NumberOfClicks}} 9 <button ng-click="onClick()">Click Me</button> 10 </div> 11 <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.0.1/angular.min.js"></script> 12 <script src="Scripts/Controller.js"></script> 13 </body> 14 </html>

In this example we are interested in line (9). Angular provides a cool directive ‘ng-click’ which will listen to the click event and calls a function in the controller or if it is an expression then it evaluate the expression. It is as simple as that. So in Angular, if you want to use commanding to do clean separation of view and controller, all you have to do is use ng-click directive on a button. From view model perspective, the function view is calling nothing more than just another function and nothing special about it. There are bunch of APIs you can use to create this commanding behavior on different controls and you can find them all here in Angular API directive.

Controller:

1 function Controller($scope) { 2 $scope.NumberOfClicks = 5; 3 $scope.onClick = function() { 4 $scope.NumberOfClicks = $scope.NumberOfClicks + 1; 5 }; 6 }

In Silverlight, not only we can execute the action through command, we have another option enable the command or not. This can be achieved using ng-disabled directive. Will look at how to use that in the following example. One benefit in Angular is that you can pass as many parameters as you want in the function call instead of just one in Silverlight. Let’s take a look at a sample where we can pass multiple parameters in function call.

Following example allow user to enter two numbers and perform an addition and display result. When the user enters non numeric number we want to disable the ‘Sum’ button.

View:

1 <!DOCTYPE html> 2 <html ng-app> 3 <head> 4 <title></title> 5 </head> 6 <body ng-controller="Controller"> 7 First : <input ng-model="numberOne"/><br/> 8 Second: <input ng-model="numberTwo"/><button ng-disabled="IsValid(numberOne, numberTwo)" 9 ng-click="onClick(numberOne, numberTwo)">Sum</button><br/> 10 Sum: {{sum}} 11 <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.0.1/angular.min.js"></script> 12 <script src="Scripts/Controller.js"></script> 13 </body> 14 </html>

Both first and second number are two-way binding since the user change need to be propagated to model. On button click, we are using ng-click directive to call ‘onClick’ function in the controller and we are passing two parameters numberOne and numberTwo from the UI. If you notice, we also have another directive called ng-disabled, this will make the element disable if it return associated function from control returns false. If the input data collection is a form then you can enable and disable form submit button using Form.$validate.

Controller:

This is nothing but simple java script code which has variable assignments and a function call.

1 function Controller($scope) { 2 $scope.numberOne = 0; 3 $scope.numberTwo = 0; 4 $scope.sum = 0; 5 $scope.onClick = function(first, second) { 6 $scope.sum = Number(first) +Number(second); 7 }; 8 $scope.IsValid = function(first, second) { 9 return !(isNumber(first) && isNumber(second)); 10 }; 11 function isNumber(n) { 12 return !isNaN(parseFloat(n)) && isFinite(n); 13 } 14 }

One another point of interest along the line of ng-click is about other events from other elements. Take a look at this stack overflow question and answer. At the end, there is a comment by Tim Steward which is very interesting. He pointed out that if you do not see any ng- function for the element you are working on, his suggestion is to use Angular-UI

Silverlight to Angular – 1

So from my previous blog you all know that I am moving towards Angular for our front end development. I am planning to write series of blogs on how to take Silverlight knowledge to Angular. But if you want to learn Angular without the Silverlight background, please head to this great example. Without further ado, lets look at our hello world program.

Problem: We are asked to create an app, which will display ‘Hello World’.

Silverlight:

As you all know, Silverlight follows MVVM pattern. In this case, all we need to do is to display a static text ‘Hello World’. So there is no need for Model or ViewModel here. All we need is simple XAML with a TextBlock which displays ‘Hello World’ like the following

<Grid x:Name="LayoutRoot" Background="White">
    <TextBlock HorizontalAlignment="Left"  TextWrapping="Wrap" Text="Hello World" VerticalAlignment="Top"
               Height="25" Width="289"/>
</Grid>

So in here XAML is the ‘V’ ( – View) in the ‘MVVM’. Nothing complicated here, very simple. Compile and run the app and you will get a very simple ‘Hello World’.

Angular:

Now switching the focus to Angular world. Before we dig deep into Angular, we need to understand what is Front End Framework (FeF). If you are to develop application using HTML, you would use HTML for rendering page, CSS for styling and Javascript to handling client side processing. To create a dynamic, responsive web page, we will need to lot of work with Javascript and ton of DOM manipulation. So here is where FeF to help. There are ton of FeF is available today. They all abstract the common tasks that we would do and make our development easy to create responsive and cross browser support (with limitation) application. With FeF, we can focus on building our application rather than worry about browsers and ugly DOM manipulation.  Angular is one such framework backed by Google. I do not want to go into details of what it gives out of the box since it is very well documented in angular website.

Before we go into Angular development, have a look at a mapping between Angular and Silverlight.

clip_image001[6]
clip_image002[6]

Angular framework also support and promotes MV* model development. Igor from Angular wrote a short take on whether Angular is a MVC or MVVM and his conclusion is Angular is MVW pattern where ‘W’ stands for whatever you want it to be, Controller or View Model. Sticking with Silverlight model, I will try to related to VM as we go along. Coming back to the problem at hand, what we need to display is a static ‘Hello World’ text and in our Silverlight application, we put the text directly in the view and that is what we are going to do here as well. Going by above picture all we need to do is to put ‘Hello World’ and we are done. So here is the simple HTML which displays ‘Hello World’.

head>
    <title></title>
</head>
    <body>
        <p>Hello World</p>
    </body>
</html>

So your question is, where is Angular? You do not need Angular since all our work is in the View. In FeF, the view is nothing more than HTML (for now).

If I stop the blog right here, then I am really cheating, we did not see any Angular here. So we are going to modify the problem little bit different. So here is the new problem statement.

Problem: We are asked to create program to display a value of string variable ‘DisplayData’, where ‘DisplayData’ contains ‘Hello World’.

Silverlight:

(You can get the full solution of Silverlight and Angular from https://www.dropbox.com/sh/nh7ihjrqlhiax02/RrkmDC-6qL)

As you know from my previous blogs, I am a big fan of Jounce framework for my Silverlight development. If you are not familiar with Jounce framework, don’t worry, the concepts we are going to look at should be easy to follow. If you are a hard core Silverlight developer and not using any MVVM framework, I would strongly recommend you to take a look at this framework. Anyway, Lets look at the code we would write to display ‘Hello World’ from view model.

View: (MainPage.XAML)

<Grid x:Name="LayoutRoot" Background="White">
        <TextBlock HorizontalAlignment="Left"  TextWrapping="Wrap" Text="{Binding DisplayData}" VerticalAlignment="Top"
                   Height="25" Width="289"/>
    </Grid>

 

ViewModel:

public class MainPageViewModel:BaseViewModel
    {
        public string DisplayData
        {
            get { return "Hello World"; }
        }
    }

Jounce has couple of ways to do the view and viewmodel association. I am using traditional explicit Export attribute to mark view and viewmodel and let Jounce do the mapping. As a Silverlight developers we know how this thing work and how data binding happen so I will stop here.

Angular:

One of the main reason I am really attracted to Angular is the out of the box data binding. By the way Knockout framework also support data binding like Silverlight. Lets start our actual Angular code. Even though it is simple Hello World, I would like to follow same MVC pattern. First and fore most, I am doing all the development in Visual Studio 2012. I will do a quick walk through on what do I do for HTML5 development.

  1. For our testing either you can download angular.js locally and use that for our coding or point directly to the minified version in the web.
  2. Create a directory where you want to create the new html page.
  3. Open Visual Studio and create new ‘Blank Project’. (If you do not see it, search for blank template on search it will show up).
  4. Select Solution and Add existing web page and use file system and point to the empty directory you have created.
  5. Create a new folder called ‘Scripts’ where we will keep all the java scripts.

View: (Home.html)

<!DOCTYPE html>
<html ng-app>
<head>
</head>
    <body>
        <div ng-controller="Controller">{{DisplayData}}</div>
        <script src="http://code.angularjs.org/1.0.5/angular.min.js"></script>
        <script src="Scripts/Controller.js"></script>

    </body>
</html>

 

Controller: (scripts\Controller.js)

function Controller($scope) {
    $scope.DisplayData = "Hello World";
}

So there are two code, one is HTML and another one is pure java script. Lets look at the HTML first and see if we can make any sense of it.  To make it simple, let us focus only on the bolded words, rest of it normal HTML.

  1. ng-app: Every angular application should have one and only ng-app. When HTML is been rendered on the browser, once Angular gets the execution context, it will try to find the application scope. In our case, we have ng-app set at <HTML> tag that means, angular will look for angular directives in all DOM elements. We can even have the ng-app set to a simple and single <DIV>, then the scope is limited to the <DIV>. The bottom line, you need to have one ng-app.
  2. ng-controller: This is one of the important directive you need to know. This is the one which connects, view to the controller like the ‘[Export]’ we did in Silverlight. You can have multiple controller in a single view (HTML) but only one ng-app. In our example, we have one controller called ‘Controller’ assigned to a <DIV> DOM object. So everything under DIV will get evaluated with this associated controller.
  3. {{variable}}: The double curly braces are nothing but data binding or ‘{Binding variable}’ in Silverlight. Same as in Silverlight, when you use a Binding variable, Silverlight will look for it in the associated ViewModel, in this case, Angular will replace the variable with value from associated controller.

If you are interested in how these ng- directives are processed and how you got the hello world, instead of me repeating it as third person, take a look at this awesome information in Angular web site.

Next stop is controller script. This script is very simple. We have a controller object and it gets its scope as a parameter. If you remember, in the view, you can set the ng-controller to any DOM element. The $scope is suppose to cover all the DOM elements with in it. So in our example, the controller is associated with all the elements under the <DIV> element. So when angular process the DOM elements, it will look for DisplayData under Controller object and it find the ‘Hello World’ and populates the  value.

If you have any questions or doubt, please send me a note and I will try to answer. When you are working through the examples, if you run into any problems, I would recommend check out Forum at Stack Overflow.

Silverlight to Angular JS

With heavy and broken heart finally it is time for me to say good bye to one of the best technology that I worked with,  ‘Silverlight’. There is always people argue about the validity and are so happy about the Silverlight demise. In my opinion as a developer, I really enjoyed developing apps in Silverlight. The best part of course was data binding. So simple concept that made the coding very easy and also the separation of view and view model so clean. XAML was so easy to create view without getting too much business and so on. Now we are not talking about Silverlight but the next big thing. It is without doubt HTML5, Microsoft was very quick and wise to adopt it. As the technology progress, it is time for me to make the switch as well. So lately I started poking at various options available today to make the transition into HTML5.

As a silverlight developer, I follow John Papa and he is been promoting Knockout JS. I saw couple of videos and did some coding with it and it looks good. From Silverlight,  it is a natural transition. While Knockout is pretty good, there is another cool kid in the block and is Angular JS. Similar to Knockout, Angular also have great tutorials, decent following in forums. One of the things I was looking for when I started learning Angular of course is data binding and it is rich. I fell in love with it on my second data binding exercise. So I am going to head into HTML5 with Angular for client side development. I have not decided on the server side technologies yet. If any one have any good comments or suggestions please feel free to send me a note or command.

Some good references for Angular:

Home – http://angularjs.org/

Screencasts – http://www.egghead.io/

Blogs – http://blog.angularjs.org/

As I move from Silverlight to Angular I found a better IDE to go with it. Webstrom is so far the best IDE I found for angular development.

So my friend ‘Silverlight’ Good Bye.

Silverlight 4 – Drop target example

One of the feature that stand out most in SL4 is drop target other than Print. I am sure most of all of you run into a user story where the user need to drag and drop a file over some web control. Well I will not blame user, since Win XP, most of the desktop application let user do that, so why not the web application do it.

I got some time yesterday night and gave it a try. It turned out to be so easier than I thought it would be.

The objective of my test was to drop a text file over to a text block and display the content in the text block. Very simple. Here are the things I did. Remember this will work only in Silver light 4.

1. Create a silverlight application in VS2010.

2. Open the designer and drop a text block on to the grid control.

3. In the MainPage.xaml, add ‘AllowDrop’ and ‘Drop’ attributes to TextBlock so the modified one will look like this

<Grid x:Name=”LayoutRoot” Background=”White”>

       <TextBlock Height=”229” HorizontalAlignment=”Left” Margin=”64,27,0,0” Name=”textBlock1” VerticalAlignment=”Top” Width=”266’” AllowDrop=”True” Drop=”textBlock1_drop” />

</Grid>

4. Now in the code behind, we need to add the textBlock1_drop method. (If the method is already there change the body)

private void textBlock1_drop(object sender, DragEventArgs e)

{

     FileInfo[] dropFileInfo = e.Data.GetData(DataFormats.FileDrop) as FileInfo[];

     if (dropFileInfo.Count() > 0)

     {

           StringBuilder fileContent = new StringBuilder();

           using (StreamReader dropFileStream = fi[0].OpenText())

                  fileContent.Append(dropFileStream.ReadToEnd());

           textBlock1.Text = fileContent.toString();

     }

}

 

That is it, now compile and run it. You will see a web page with content ‘TextBlock’,. Open Windows explorer and drag a text file and drop it over ‘TextBlock’, it should now show you the content of the text file.

Even though We get the file info in drop event, you can not access the file directly from the physical file location, you should only use the file stream to read the content. It is because of the sandbox restriction.

Enjoy.

Technorati Tags: ,