Wednesday, November 18, 2009

Silverlight 4 BETA – A first look

Today Silverlight 4 beta was released !!

New with Silverlight 4 is a lot of features, a whole list of new stuff has been released, many of which are things I was really looking forward to ( native support for commands, binding on dependency objects, right clicking,text trimming , …).

So what are all the new features in Silverlight, well there is a whole list that can be found on the Blog of Tim Heuer.

http://timheuer.com/blog/archive/2009/11/18/whats-new-in-silverlight-4-complete-guide-new-features.aspx

You can expect a number of posts on Silverlight 4 in the coming days, as I am exploring this new version.

Exiting stuff !

Monday, November 16, 2009

Commanding with PRISM in Silverlight 3

You have probably already heard about PRISM, but in case you, like me, have not really looked at it I thought I would write a small intro to using commands in PRISM.

What is PRISM ?

The Composite Client Application Guidance is designed to help you more easily build modular Windows Presentation Foundation (WPF) and Silverlight client applications. These types of applications typically feature multiple screens, rich, flexible user interaction and data visualization, and role-determined behavior. They are "built to last" and "built for change."

Source : http://www.codeplex.com/CompositeWPF/

Prism is a much broader field then just commanding, and I will spend a few future blogpost in explaining it a bit more in detail, but for now I am just going to talk about using Commands.  Why, could you ask, well the main reason is that this is the biggest thing I was missing in Silverlight, a way to define ( in XAML ) how we want our UI to behave without having to attach unreadable event handlers like we would normally do.

For a detailed explanation on how commanding works you could visit the msdn website, but for a simple, back to basics solution, please read on.

MVVM

To illustrate our point we are going to create an MVVM application, what MVVM is and how we should work with it is something we will talk about in one of my next posts.  The think here is that we will not have any code behind in our View ( Page ) and we will databind our ViewModel to it to be able to do some commanding.

The XAML code :

This is the xaml code we will place in our view class, for example “MainPage.xaml”, the code behind will be empty, appart from the standard InitializeComponent() call.

<UserControl.DataContext>
<local:ViewModel/> 
</UserControl.DataContext>
<Grid x:Name="LayoutRoot"> 
<StackPanel Orientation="Vertical">
 
<TextBlock Text="Please enter the answer : "/>
 
<TextBox Text="{Binding TextValue}" x:Name="answer"/>
  <Button Content="Ok" composite:Click.Command="{Binding ConfirmCommand}" 
     composite:Click.CommandParameter="{Binding ElementName=answer,
   
Path=Text}"  /> 
<StackPanel>
</Grid>

The ViewModel

This is the ViewModel, this is a concept that I will explain in further detail in future posts, but the idea is that this ViewModel is databound to the View ( as we can see in the DataContext property in the View )

public class ViewModel : INotifyPropertyChanged

public ViewModel()

//Initialize the command, hooking up the execute method and the canexecute method 
ConfirmCommand = new DelegateCommand<string>(execute, canExecute);
}

 

/// <summary>
/// Execute the command when it was clicked
/// </summary>
/// <param name="parameter">The Command Parameter that was given</param> 
private void execute(string parameter) 

MessageBox.Show(string.Format("You have succesfully answered : {0}", parameter)); 

/// <summary> 
/// Can we execute the command, this will disable the related control if it cannot
/// </summary> 
/// <param name="parameter">The command parameter that was given</param>
/// <returns>Can the command execute</returns>
private bool canExecute(string parameter)
{
//Can we execute the command
return parameter == "42";
}

private string textValue;
/// <summary>
/// Definition of our bindeable TextValue, with a trigger to update the UI
/// </summary>

public string TextValue
{
get { return textValue; }
set
{
 
textValue = value;
  //Notifiy the property has changed
  InvokePropertyChanged("TextValue");
  //Notify the command that the conditions to execute have changed
  ConfirmCommand.RaiseCanExecuteChanged();
}
}

public DelegateCommand<string> ConfirmCommand { get; set; } 

/// <summary>
/// Track changes to the Properties, so the UI can know when to update the bindings.
/// </summary>

public event PropertyChangedEventHandler PropertyChanged;

private void InvokePropertyChanged(string property){
 
if (PropertyChanged != null)
   
PropertyChanged(this, new PropertyChangedEventArgs(property));
}
}

So what exactly does this application do ?  Well basically it check if your entered text in a textbox is equal to “42” and enables the Button if so.  Nothing to complicated, just the answer to life the universe and everything (link).

Conclusion

I hope it is clear by this example what power Commanding has in Silverlight ( just like in WPF ) and how we can benefit from using it more extensively. Mainly the CanExecute makes a huge difference in how you can easily allow an application to respond to your input and adapt.

Saturday, November 7, 2009

Silverlight Rx : System.Reactive

Yesterday I came across the System.Reactive assembly that is included with the Silverlight Toolkit.  On the blog of Jafar Husain

He has made a lot of posts about the Rx framework, and it is definitely interesting to read!

http://themechanicalbride.blogspot.com/2009/07/introducing-rx-linq-to-events.html

We can program in reaction to events and apply our logic on them. We could for example do some action only when an event is raised with a certain event argument. This embeds the Async handling of events and allows this code to be unit tested.

The big problem with asynchronous programming is that the code very quickly gets unreadable and hard to maintain, as it is not always clear how several events are linked to one another.

The Reactive framework works with the IObserver and the IObservable classes, which can be thought of as Reactive versions of IEnumerable in the context of Linq ( actually the extension methods have been added to the System.Linq namespace ).  You basically look at the events being thrown as a collection you can browse trough.

So how does it work.

To quickly show how we can use Rx to simplify our code, We will write an extension method that will call a web client's DownloadString method and return a String.

public static class WebClientExtender
{

public static IObservable<string> GetSite(this WebClient client, string url)
{
var downloaded = Observable.FromEvent<DownloadStringCompletedEventArgs>
                 (client, "DownloadStringCompleted");
client.DownloadStringAsync(new Uri(url));
return downloaded.Select(x=>((DownloadStringCompletedEventArgs)x.EventArgs).Result);
}

}

To call this we can now simple add the following line of code to our Silverlight application.

new WebClient().GetSite("http://localhost/").Subscribe(x => MessageBox.Show(x));

This way we can very easily clean up the code and structure how the Asynchronous events are handled.

Sunday, November 1, 2009

CollectionViewSource in Silverlight

What is CollectionViewSource

The CollectionViewSource is a class that is used in WPF to apply sorting and filtering on Data. We can also use this class in Silverlight 3.
I came across it while studying for my WPF exam and noticed it was also available in Silverlight. So naturally I had a look. It is very easy to use as I will demonstrate below.

So lets have a look.

In this case, we have List of Person we want be able to Filter and Sort correctly.

A person could be defined like this :

public class Person
{
public String FirstName { get; set; }
public String LastName { get; set; }
}

To be able to use a CollectionViewSource we can define it as a resource in our XAML, we could also define it in code, but for this example we will write most in XAML.

<UserControl.Resources>
<local:PersonDataSource key="data">
<CollectionViewSource Source="{Binding Source={StaticResource data}}" x:Key="CollVS">
<CollectionViewSource.SortDescriptions>
<ComponentModel:SortDescription Direction="Descending">
</CollectionViewSource.SortDescriptions>
</CollectionViewSource>
</UserControl.Resources>

You see here that we defined a "data" datasource, we should create a class that will be able to store the information we need, lets call it PersonDataSource. We could also add some logic here to return some dummy data for now. For this example I chose to simply inherit from ObservableCollection and not add any additional logic, obviously you could use any collection here you would normally use to bind to a datagrid.

To finish our XAML UI, we add a DataGrid to display our data and a TextBox we can use for filtering. In our case we will apply filtering on the LastName.

<StackPanel Orientation="Vertical">
<data:DataGrid ItemsSource="{Binding Source={StaticResource CollVS}}"/>
<TextBox x:Name="filter"/>
</StackPanel>

Now we can define how we are going to do our filtering and make sure the filtering is visible in the User interface.

public MainPage()
{
InitializeComponent();
//Get the CollectionViewSource from the Resource of the UserControl
CollectionViewSource CollVS = (CollectionViewSource)Resources["CollVS"];
//Make sure we update the datagrid when we change our filter
filter.TextChanged += delegate { CollVS.View.Refresh(); };
//Subscribe to the filter event
CollVS.Filter += cvs_Filter;
}

void cvs_Filter(object sender, FilterEventArgs e)
{
e.Accepted = ((Person)e.Item).LastName.ToLower().StartsWith(filter.Text.ToLower());
}

So what did we do here ? First we needed to get our CollectionViewSource from our Resources. The most important thing here is that we do the following :

filter.TextChanged += delegate { CollVS.View.Refresh(); };

If we don't do this, our view will not update and we will not be able to see our filter.

To filter, we can change if an Item should be filtered by setting the Accepted property , the Filter will be called for every element in your collection.

The last step is to implement IComparable on our Person object , this is required by the CollectionViewSource to apply sorting on the Collection. The data will now be automatically sorted as it is filtered.