Using Silverlight 2 ItemsControl Templates

Building Silverlight 2 applications reminds me of the first time I built an ASP.NET application.  There are so many new features and controls that it takes a little time to get up-to-speed with what's available and how it can be used.  It's definitely fun but at times you just want to throw the monitor out the window when something doesn't work like you think it should (disclaimer:  I've never actually thrown a monitor anywhere...but I'm definitely guilty of wanting to do it).  The good news is that the learning curve flattens out pretty quickly once you grasp a few key concepts which probably makes my monitor feel much better.  :-)

I was building a sample application for a Silverlight 2 book I'm working on and after I finished a particular feature I realized that there was an easier way to do what I wanted without writing much C# code.  I needed to dynamically output Rectangles with images and was doing it all programmatically mainly because it was comfortable and easy to do.  Here's an example of the code I initially wrote:

foreach (Model.Photo photo in photos)
{
    Rectangle rect = new Rectangle();
    rect.Stroke = new SolidColorBrush(Colors.Gray);
    rect.StrokeThickness = 2D;
    rect.RadiusX = 15D;
    rect.RadiusY = 15D;
    rect.Height = 75D;
    rect.Width = 75D;
    ImageBrush imgBrush = new ImageBrush();
    imgBrush.ImageSource = new BitmapImage(new Uri(photo.Url));
    imgBrush.Stretch = Stretch.Fill;
    rect.Fill = imgBrush;
    rect.Tag = photo.Url;
    rect.MouseLeftButtonDown += new MouseButtonEventHandler(rect_MouseLeftButtonDown);
    rect.Margin = new Thickness(10D);
    this.wpImages.Children.Add(rect);
}


The code worked fine and I was able to generate the desired output for the interface.  It never felt quite right though....it seemed too code intensive for such a simple task.

In researching some other controls available in Silverlight 2 I came across ItemsControl which turns out to be what I needed in the first place.  ItemsControl allows a panel template to be defined (StackPanel, Canvas, Grid, etc.) as well as an items template.  It's like the DataList in ASP.NET in some ways.  Using it allows a collection of objects to be data bound and output without having to write custom looping code with C# or VB.NET.  Here's an example of using ItemsControl in XAML:

<ItemsControl x:Name="icPhotos" Grid.Row="1">
    <ItemsControl.ItemsPanel>
        <ItemsPanelTemplate>
            <wp:WrapPanel x:Name="wpImages" Margin="10" Orientation="Horizontal" />
        </ItemsPanelTemplate>
    </ItemsControl.ItemsPanel>
    <ItemsControl.ItemTemplate>
        <DataTemplate>
            <Rectangle Stroke="LightGray" Tag="{Binding Url}" Fill="{Binding ImageBrush}" StrokeThickness="2" 
                       RadiusX="15" RadiusY="15" Margin="15"
                       Height="75" Width="75" Loaded="Rectangle_Loaded" MouseLeave="Rectangle_MouseLeave" 
                      MouseEnter="Rectangle_MouseEnter"  MouseLeftButtonDown="Rectangle_MouseLeftButtonDown">
                <Rectangle.RenderTransform>
                    <TransformGroup>
                        <ScaleTransform ScaleX="1" ScaleY="1" CenterX="37.5" CenterY="37.5" />
                    </TransformGroup>
                </Rectangle.RenderTransform>
            </Rectangle>                            
         </DataTemplate>
    </ItemsControl.ItemTemplate>
</ItemsControl>


This code uses a really nice WrapPanel control created by lneir as the panel template.  The WrapPanel control automatically wraps UIElements to the next line once the width of the screen has been exceeded.  The ItemTemplate defines a data template that outputs a Rectangle with an ImageBrush used for the fill as objects are bound.

Once the templates were defined I was able to bind my photo collection to the ItemsControl control (named icPhotos) using the following code.  Very nice and more along the lines of what I'm used to doing with ASP.NET controls.

this.icPhotos.ItemsSource = photos;

In working through the XAML and code I learned a trick about binding an ImageBrush to the Fill property of a UIElement which I'll blog about soon.

comments powered by Disqus

1 Comment

Comments have been disabled for this content.