Wednesday, November 25, 2009

ItemsControl – A simple way to edit and display lists of objects

This control makes me remind of the Repeater control in ASP.NET. It is quite easy to create a very simple list of objects using it. It simply creates one instance of the controls inside the DataTemplate tag per each element in the enumerable object that is bound to ItemsSource.

   1: <navigation:Page x:Class="PlayWithSilverlightControls.Views.PlayWithItemsControl"
   2:            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
   3:            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
   4:            xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
   5:            xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
   6:            mc:Ignorable="d"
   7:            xmlns:navigation="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Navigation"
   8:            d:DesignWidth="640" d:DesignHeight="480"
   9:            Title="PlayWithItemsControl Page">
  10:  
  11:     <Grid x:Name="LayoutRoot">
  12:         <Grid.RowDefinitions>
  13:             <RowDefinition Height="*" />
  14:             <RowDefinition Height="30" />
  15:         </Grid.RowDefinitions>
  16:         <ItemsControl ItemsSource="{Binding ModelItems}">            
  17:             <ItemsControl.ItemTemplate>
  18:                 <DataTemplate>
  19:                     <StackPanel Margin="3,10,0,0">
  20:                         <Rectangle Height="2" Fill="Black" />
  21:                         <TextBlock Text="{Binding Name}" />
  22:                         <TextBox Text="{Binding Comment}" />
  23:                     </StackPanel>
  24:                 </DataTemplate>
  25:             </ItemsControl.ItemTemplate>
  26:         </ItemsControl>
  27:         <StackPanel Grid.Row="1" Orientation="Horizontal" HorizontalAlignment="Right" Height="25">
  28:             <Button Content="Submit" Width="150"/>
  29:             <Button Content="Cancel" Width="150"/>
  30:         </StackPanel>
  31:     </Grid>
  32: </navigation:Page>

I used this very simple ViewModel to render some data:

   1: public class Model
   2:     {
   3:         public string Name
   4:         {
   5:             get;
   6:             set;
   7:         }
   8:  
   9:         public string Comment
  10:         {
  11:             get;
  12:             set;
  13:         }
  14:     }
  15:  
  16:     public class PlayWithItemsControlViewModel
  17:     {
  18:         private ObservableCollection<Model> items = new ObservableCollection<Model>();
  19:  
  20:         public PlayWithItemsControlViewModel()
  21:         {
  22:             this.items.Add(new Model { Name = "Model A" });
  23:             this.items.Add(new Model { Name = "Model B" });
  24:             this.items.Add(new Model { Name = "Model C" });
  25:             this.items.Add(new Model { Name = "Model D" });
  26:             this.items.Add(new Model { Name = "Model E" });
  27:         }
  28:  
  29:         public IEnumerable<Model> ModelItems
  30:         {
  31:             get
  32:             {
  33:                 return this.items;
  34:             }
  35:         }
  36:     }

The Model class is not implementing core interfaces such as INotifyPropertyChanged or IEditableObject and therefore most Silverlight features will not work with it. I hope to post some notes on how these interfaces can be implemented and used to enable those features.

We can quickly see the results by placing this code on the view code behind:

   1: // Executes when the user navigates to this page.
   2: protected override void OnNavigatedTo(NavigationEventArgs e)
   3: {
   4:      this.DataContext = new PlayWithItemsControlViewModel();
   5: }

I think it is a good practice to use the ViewModel as the DataContext of the Page and to define bindings assuming just that.

To host it create a Navigation application and go to the MainPage.xaml and add a new navigation button at the bottom of the xaml:

   1: <Rectangle x:Name="Divider2" Style="{StaticResource DividerStyle}"/>
   2:  
   3: <HyperlinkButton x:Name="Link3" Style="{StaticResource LinkStyle}" 
   4:     NavigateUri="/PlayWithItemsControl" TargetName="ContentFrame" Content="Items Control"/>

Have fun,

Tuesday, November 24, 2009

Moq – Port to Silverlight 4

 

If you are in love with TDD you know Moq. It is one of the best Mocking frameworks out there… I’m working on SL4 and could not live without it! The problem is binaries for SL4 are not available yet.

To compile Moq on Silverlight 4 you just need the Castle dlls compiled for the runtime 4 and to recompile the source code. I ported the castle source code to Silverlight 4 and sent the patch to Castle project. Hope this will get on trunk soon. In the meantime you can download Moq and Castle compiled to SL4 here:

Castle.Core

Castle.DynamicProxy2

Moq Debug Compilation

Moq Release Compilation

Moq Source Code with updated projects

Have fun,