Carey's profilemoved to www.codingbandi...PhotosBlogLists Tools Help

Blog


    November 15

    WPF Data Templates Part 4 - Template Selectors

    *Note - Class Definition and sample data used in this example are provided in this previous blog post.

    Template Selectors allow you to switch the Data Template used on an item being bound based on some logic.  For instance, in a banking application, you may wish an account that has a negative balance to be highlighted with a red background in order to draw the attention of the user.  Other positive balance accounts can be rendered using a different, milder looking template.  To implement a Template Selector, use inheritance through extending the System.Windows.Controls.DataTemplateSelector and overriding the SelectTemplate method. The signature of the method is as follows:

     
            public override System.Windows.DataTemplate SelectTemplate(object item, System.Windows.DependencyObject container)
     
           

    In this case, item is the actual object being bound.  You can analyze the properties of the object to determine which template to use when rendering.  In this example, the data template selector will be performing logic on the ImageFavorite class to determine which template to use.  Two data templates have been defined in resources, one being a summary view defined by the SimpleTemplate key, and a more detailed view defined by the DetailedTemplate key.   The logic of the RatedImageTemplateSelector is if the item [ImageFavorite] being bound has a 5 star rating, utilize the detailed template, otherwise have it render using the simple template.  The listing for the RatedImageTemplateSelector is as follows:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Windows.Controls;
    using System.Windows;
     
    namespace TemplateSelector
    {
        public class RatedImageTemplateSelector : DataTemplateSelector
        {
            public override System.Windows.DataTemplate SelectTemplate(object item, System.Windows.DependencyObject container)
            {
                ImageFavorite obj = item as ImageFavorite;
                ContentPresenter pres = container as ContentPresenter;
                DataTemplate dataTemplate;
     
                if (obj.ImageRating == 5)
                    dataTemplate = pres.FindResource("DetailedTemplate") as DataTemplate;
                else
                    dataTemplate = pres.FindResource("SimpleTemplate") as DataTemplate;
     
                return dataTemplate;
            }
        }
    }
    In order to utilize the template selector, you need to first declare its namespace in the window tag of the xaml file where it is being used.  In this case the namespace is TemplateSelector which resides in the current project assembly:
    xmlns:local="clr-namespace:TemplateSelector"
    Then define an instance of the template selector in resources:
    <local:RatedImageTemplateSelector x:Key="RatedImageTemplateSelector" />
    This instance of the RatedImageTemplateSelector can now be used by the list box rendering ImageFavorite items by assigning it to the ItemTemplateSelector attribute:
    <ListBox x:Name="lbResults" Grid.Row="1" Grid.Column="0" Height="240"
                     HorizontalContentAlignment="Stretch" 
                     ItemsSource="{StaticResource FavoriteImages}"
                     ItemTemplateSelector="{StaticResource RatedImageTemplateSelector}" />

    Screen shot of two different data templates being rendered in a list box based on logic defined in a template selector:

    image

    Sample code for this example can be found here

    WPF Data Templates Part 3 - Switching Data Templates at Runtime

    *Note - Class Definition and sample data used in this example are provided in this previous blog post.

    It's a known fact that users like to have options.  Sometimes one user is more familiar with the data being displayed than another, and would to see only a summary of the data. New users of the application may prefer to see a more detailed view of the data.  WPF makes it easy to define multiple Data Templates and switch them out based on user preference.  To do this, you can define Data Templates as resources, and reference them by key to use them.  These data templates are defined in Window.Resources:

    <DataTemplate x:Key="DetailedTemplate">
        <Border BorderBrush="Blue" Margin="3" Padding="3" BorderThickness="2" CornerRadius="5" Background="Beige">
            <StackPanel Orientation="Horizontal">
                <Image Margin="10" Width="250" Height="200" Stretch="Fill" Source="{Binding Path=ImageHref}">
                    <Image.BitmapEffect>
                        <DropShadowBitmapEffect />
                    </Image.BitmapEffect>
                </Image>
                <StackPanel Orientation="Vertical" VerticalAlignment="Center">
                    <TextBlock FontSize="25" Foreground="Goldenrod" Text="{Binding Path=ImageName}" />
                    <Label Content="{Binding Path=ImageRating,Converter={StaticResource RatingConverter}}" />
                </StackPanel>
            </StackPanel>
        </Border>
    </DataTemplate>
     
    <DataTemplate x:Key="SimpleTemplate">
        <Border BorderBrush="Blue" Margin="3" Padding="3" BorderThickness="2" CornerRadius="5" Background="Beige">
            <StackPanel HorizontalAlignment="Center">
                <Image Margin="10" Width="250" Height="200" Stretch="Fill" Source="{Binding Path=ImageHref}">
                    <Image.BitmapEffect>
                        <DropShadowBitmapEffect />
                    </Image.BitmapEffect>
                </Image>
            </StackPanel>
        </Border>
    </DataTemplate>
    You can set the default Data Template of the list box directly in XAML using its ItemTemplate property and referencing the desired template from resources identified by its key [in this case we are starting out with the summary template defined by the SimpleTemplate key in resources]:
    <ListBox x:Name="lbResults" Grid.Row="1" Grid.Column="0" Height="240" 
        HorizontalContentAlignment="Stretch" ItemsSource="{StaticResource FavoriteImages}"  
        ItemTemplate="{StaticResource SimpleTemplate}" />
    Next we'll add buttons to the screen so that the user can toggle the Summary and Detail view of the data being contained by the List Box.
    <Button Content="Details" Margin="5,0,0,0" x:Name="btnDetail" Click="btnDetail_Click" />
    <Button Content="Summary" Margin="5,0,0,0" x:Name="btnSummary" Click="btnSummary_Click" />
    In the code-behind, by reacting to user actions, we can now change the Data Template of the list box by pulling the desired Data Template programmatically from resources and changing the ItemTemplate property value:
    private void btnDetail_Click(object sender, RoutedEventArgs e)
    {
        //pull the detailed template from resources, identified by the DetailedTemplate key
        DataTemplate detail = this.FindResource("DetailedTemplate") as DataTemplate;
        lbResults.ItemTemplate = detail;
    }
     
    private void btnSummary_Click(object sender, RoutedEventArgs e)
    {
        //pull the summary template from resources, identified by the SimpleTemplate key
        DataTemplate summary = this.FindResource("SimpleTemplate") as DataTemplate;
        lbResults.ItemTemplate = summary;
    }

    Summary Template:

    image

    Detailed Template:

    image

    Full source code for this sample is available here.

    November 02

    WPF Data Templates Part 2 - Value Converters

    Sometimes the value you want to display needs to be transformed from the original data before being bound to a XAML element. For instance, formatting a telephone number, or adding brackets to a negative balance on an account.  To accomplish this task a Value Converter is used.  A Value Converter is simply a class that implements the IValueConverter interface (located in the System.Windows.Data namespace).  This interface contains two methods, Convert, and ConvertBack.  It is not necessary to implement the ConvertBack method unless you are persisting data back to a data source and need the reverse transformation from the visual back to the persisted value.  It is important to remember that Value Converters can take in any value and return any type of object, for instance, an integer can be transformed into a string, and a string can be turned into a user control.   In the example provided below, an integer value is converted to a User Control that has the ability to display a 5 star rating.  Here is the XAML of the FiveStarRating user control which is made up of 5 paths in the shape of a star:

    <UserControl x:Class="ValueConverter.FiveStarRating"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
        <Canvas xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
            <StackPanel Orientation="Horizontal">
                <Path x:Name="Star1" Margin="0,15,5,0" Stroke="Black" StrokeThickness="2"  StrokeLineJoin="Round" Data="M 0,0 l 10,0 l 5,-10 l 5,10 l 10,0 l -7,10 l 2,10 l -10,-5 l -10,5 l 2,-10 Z" />
                <Path x:Name="Star2" Margin="0,15,5,0" Stroke="Black" StrokeThickness="2"  StrokeLineJoin="Round" Data="M 0,0 l 10,0 l 5,-10 l 5,10 l 10,0 l -7,10 l 2,10 l -10,-5 l -10,5 l 2,-10 Z" />
                <Path x:Name="Star3" Margin="0,15,5,0" Stroke="Black" StrokeThickness="2"  StrokeLineJoin="Round" Data="M 0,0 l 10,0 l 5,-10 l 5,10 l 10,0 l -7,10 l 2,10 l -10,-5 l -10,5 l 2,-10 Z" />
                <Path x:Name="Star4" Margin="0,15,5,0" Stroke="Black" StrokeThickness="2"  StrokeLineJoin="Round" Data="M 0,0 l 10,0 l 5,-10 l 5,10 l 10,0 l -7,10 l 2,10 l -10,-5 l -10,5 l 2,-10 Z" />
                <Path x:Name="Star5" Margin="0,15,5,0" Stroke="Black" StrokeThickness="2"  StrokeLineJoin="Round" Data="M 0,0 l 10,0 l 5,-10 l 5,10 l 10,0 l -7,10 l 2,10 l -10,-5 l -10,5 l 2,-10 Z" />
            </StackPanel>
        </Canvas>
    </UserControl>

    Source code for the FiveStarRating user control is as follows, contains the logic to fill the correct number of stars dependent on the Rating property of the instance:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Data;
    using System.Windows.Documents;
    using System.Windows.Input;
    using System.Windows.Media;
    using System.Windows.Media.Imaging;
    using System.Windows.Navigation;
    using System.Windows.Shapes;
     
    namespace ValueConverter
    {
        /// <summary>
        /// Interaction logic for FiveStarRating.xaml
        /// </summary>
        public partial class FiveStarRating : UserControl
        {
            public int Rating
            {
                get { return (int)this.GetValue(RatingProperty); }
                set {
                    if (value > 5)
                        value = 5;
                    if (value < 0)
                        value = 0;
     
                    this.SetValue(RatingProperty, value); }
            }
     
            public static readonly DependencyProperty RatingProperty = DependencyProperty.Register("Rating", 
                        typeof(int),typeof(FiveStarRating),
                        new FrameworkPropertyMetadata(0, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, new PropertyChangedCallback(RatingValueChanged)
                        ));
     
            public FiveStarRating()
            {
                InitializeComponent();
                
                
            }
     
            private static void RatingValueChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
            {
     
                FiveStarRating x = sender as FiveStarRating;
                int ratingValue = (int)e.NewValue;
     
                for (int i = 1; i <= 5; i++)
                {
                    Path clearStar = (Path)x.FindName("Star" + i);
                    clearStar.Fill = new SolidColorBrush(Colors.Gray);
                }
                for (int i = 1; i <= ratingValue; i++)
                {
                  
                   Path starFilled = (Path)x.FindName("Star" + i);
                   starFilled.Fill = new SolidColorBrush(Colors.Goldenrod);
                    
                }
             
            }
        }
       
    }

    The Rating property of the FiveStarRating user control has been defined as a DependencyProperty, so it is possible to bind directly to it, but in this example, we will be using this user control as the result of a value converter transformation instead.  The class definition and data being bound is defined in this previous blog post.  The value converter we will implement will convert the integer ImageRating value and transform it into a bound FiveStarRating user control.  The listing for the value converter is as follows:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Windows.Data;
     
    namespace ValueConverter
    {
        public class RatingConverter : IValueConverter
        {
            #region IValueConverter Members
     
            public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
            {
                //in order to handle design time problems, handle null value case
                if (value == null)
                    return new FiveStarRating();
               
                
                FiveStarRating uc = new FiveStarRating();
                uc.Rating = (int)value;
     
                return uc;
                 
            }
     
            public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
            {
                throw new NotImplementedException();
            }
     
            #endregion
        }
    }

    In order to utilize this Value Converter during data binding, it must first declare the namespace in the window tag, in this case the namespace is ValueConverter which resides in the current project assembly:

    xmlns:local="clr-namespace:ValueConverter"

    Then define an instance of the value converter class in Resources:

    <local:RatingConverter x:Key="RatingConverter" />
    This instance of the RatingConverter can now be used in the data template.  In order to utilize the rating converter, identify the resource (identified by the key in Resources, in this case RatingConverter) and assign it to the converter property of the binding expression.
    <Label Content="{Binding Path=ImageRating, Converter={StaticResource RatingConverter}}" />

    This binding expression passes in the value stored in the ImageRating property of the object being bound into the Convert method of the RatingConverter value converter.  The value converter then instantiates a new FiveStarRating user control, assigns the integer value to its Rating property, and returns the user control instead of the original integer ImageRating value.  The user control is then rendered in the Label control.

    image

    Complete source code for this sample is available here.

    November 01

    WPF Data Templates Part 1 - Introduction to WPF Data Templates

    Look Ma!  WPF can look like Windows Forms too!

    WPF contains many similar controls that you will find in your Windows Forms toolbox.  If you really wanted your app to look and feel like Windows Forms, it is quite possible... but why?  There are other tools and techniques to provide users (and developers for that matter) with a much richer experience.  Use the best tools for the job, and for Rich Internet or Desktop applications today the answer is WPF.

    Over the years, many great applications were developed using tools that were available in the day of it's imagecreation.  Cavemen used charred sticks and clay to display great masterpieces on cave walls in order to tell their story, which is in essence a way to display the data they wished to preserve.  For the tools they had at their disposal at this time, these displays of data are impressive.  The same analogy goes for Windows Forms, I am the first to agree that there are a number of very impressive forms applications out there, for the tools available in Windows Forms these applications are genius! Fast forward to today, while still prominent, Windows Forms isn't going anywhere soon, but there is a bigger player on the block, which allows designers/developers to work together to display data in a more intuitive fashion and enables a richer user experience above and beyond decoration and animation which is for some reason has been used synonymously when defining WPF.  To me the beauty of WPF lies in a very rich data binding model used in conjunction with endless possibilities in data presentation.

    Concentrating on the presentation of data, this is the first post in a series that will show some of the power and flexibility behind WPF data binding and Data Templates.  Data Templates are used to define the way an object's data is to be displayed and presented to the user.  They can be composed of any number of XAML elements and give you unprecedented power in displaying your data.  The posts will contain examples of using a list box control, please keep in mind that the principles shown carry to other data display controls like the combo box and tree view controls.

    Displaying a Forms-like list box in WPF

    If you require a control that looks and behaves similar to a list box control in Windows Forms, it can be translated simply into using a list box control in WPF without a Data Template.  The difference being the DisplayMember property is now the DisplayMemberPath in the WPF list box control and the ValueMember property is now the SelectedValuePath.  In the sample below, ImageName and ImageId are both properties of objects being bound to the control. The data being pulled for this sample and all subsequent ones is defined in my previous blog post .

    <ListBox Background="AliceBlue" x:Name="lbResults" 
      DisplayMemberPath="ImageName" 
      SelectedValuePath="ImageId" 
      ItemsSource="{StaticResource FavoriteImages}" />

    image

    Source code for this plain list box is available here.

    A Simple Data Template

    While functional, a list box displaying a simple value is not ideal.  When binding objects to a control in this way, it leaves it up to the user to deduce whether or not the selection they are choosing is in fact the object they are looking for.  In the past, sometimes the Text value is manipulated by appending values of several of the objects properties in order to give the end-user a more informed view of the object they are selecting.  A richer experience is required, and this is where Data Templates come into play.  Here is a simple example of creating a Data Template which displays multiple properties from the objects being bound, again the data being used in defined in this blog post.  Data Templates can be made up of any number of XAML elements, below you see the use of a border around the item, as well as a series of labels in a stack panel whose content (in this case will be rendered as text) is bound to individual object properties of the ImageFavorite class.  Think of Data Templates being similar to a repeater control, the template will be repeated for each item(object) being bound:

    <ListBox x:Name="lbResults" HorizontalContentAlignment="Stretch" 
            ItemsSource="{StaticResource FavoriteImages}">
        <ListBox.ItemTemplate>
            <DataTemplate>
                <Border BorderBrush="Blue" Margin="3" Padding="3" 
                        BorderThickness="2" CornerRadius="5">
                    <StackPanel>
                        <Label Content="{Binding ImageName}" FontWeight="Bold" />
                        <Label Content="{Binding ImageRating}" />
                        <Label Content="{Binding ImageHref}" />
                    </StackPanel>
                </Border>
            </DataTemplate>
        </ListBox.ItemTemplate>
    </ListBox>

    image

    This list box clearly shows multiple properties from the objects being listed and visually separating each item with a rounded blue border.  Presenting data in this way gives the user more information about the item that they are selecting.  Here is another example of a Simple Data Template that demonstrates the use of some other XAML elements in a Data Template (If you are running the demo code, change the StartupUri window from Window1.xaml to FancierTemplate.xaml in the App.xaml file).  The template defined below defines the display of ImageFavorite data using an Image element with a drop shadow, as well as using a Text block and label control.

    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition />
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
            <RowDefinition Height="60" />
            <RowDefinition Height="Auto" />
        </Grid.RowDefinitions>
     
        <DockPanel Height="35" Margin="10" Grid.Column="0" Grid.Row="0">
            <Border DockPanel.Dock="Top" Background="DarkBlue"  CornerRadius="5" >
                <TextBlock Text="My Favorite Images" Foreground="White" FontSize="20" 
                    HorizontalAlignment="Center" VerticalAlignment="Center"/>
            </Border>
        </DockPanel>
     
        <ListBox x:Name="lbResults" Grid.Row="1" Grid.Column="0" Height="240" 
                HorizontalContentAlignment="Stretch" 
                ItemsSource="{StaticResource FavoriteImages}" >
            <ListBox.ItemTemplate>
                <DataTemplate>
                    <Border BorderBrush="Blue" Margin="3" Padding="3"
                         BorderThickness="2" CornerRadius="5" Background="Beige">
                        <StackPanel Orientation="Horizontal">
                            <Image Margin="10" Width="250" Height="200" Stretch="Fill" 
                                    Source="{Binding Path=ImageHref}">
                                <Image.BitmapEffect>
                                    <DropShadowBitmapEffect />
                                </Image.BitmapEffect>
                            </Image>
                            <StackPanel Orientation="Vertical" 
                                    VerticalAlignment="Center">
                                <TextBlock FontSize="25" Foreground="Goldenrod" 
                                     Text="{Binding Path=ImageName}" />
                                <Label FontSize="18" 
                                     Content="{Binding Path=ImageRating}" />
                            </StackPanel>
                        </StackPanel>
                    </Border>
                </DataTemplate>
            </ListBox.ItemTemplate>
        </ListBox>
    </Grid>

    image

    Sample code for the previous two examples is available here.

    Defining your Objects with XAML in Resources to enhance your Design Time Experience

    XAML is an extremely powerful markup tool.  A less known fact is that it is possible to instantiate instances of your classes directly in markup.  This is useful in more than one way

    1. it allows you to define sample data for use in your application without reliance on external data sources.
    2. it gives you a much richer design-time experience when laying out your application (data defined in resources will automatically be displayed in the designer, for instance, when defining Data Templates, you will see the data render in the data template at design-time and not only at run-time)

    In order to define your objects in resources, you'll need to define the class of the object you will be instantiating in XAML.  In this sample the class is defined as:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
     
    namespace SimpleDataTemplate
    {
        public class ImageFavorite
        {
            public int ImageId { get; set; }
            public string ImageName { get; set; }
            public int ImageRating { get; set; }
            public string ImageHref { get; set; }
        }
    }

    Next, in the XAML file where you will be using objects of this class, you will need to add an XML namespace to the assembly in which your class definition resides. In the sample below the namespace "local" is added that references a namespace in the current project assembly (if your class is located in a separate assembly, follow the namespace with a semicolon, and the name of the assembly without extension) where the ImageFavorite class is located:

    <Window x:Class="SimpleDataTemplate.FancierTemplate"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="FancierTemplate" Height="335" Width="500"
        xmlns:local="clr-namespace:SimpleDataTemplate"> 
    <!-- the line above adds the namespace "local" to represent the local assembly -->

    In Resources you can now define instances of the ImageFavorite class.  In this example, an array of instances of the ImageFavorite class is created:

    <Window.Resources>
        <x:Array x:Key="FavoriteImages" Type="{x:Type local:ImageFavorite}">
            <local:ImageFavorite ImageId="1" ImageName="Internet Loss" ImageRating="2" ImageHref="Images/internetloss.bmp" />
            <local:ImageFavorite ImageId="2" ImageName="Magic Well" ImageRating="4" ImageHref="Images/magicwell.bmp" />
            <local:ImageFavorite ImageId="3" ImageName="ET" ImageRating="2" ImageHref="Images/ET.jpg" />
            <local:ImageFavorite ImageId="4" ImageName="Laser" ImageRating="4" ImageHref="Images/lazer.bmp" />
            <local:ImageFavorite ImageId="5" ImageName="Rims" ImageRating="5" ImageHref="Images/rims.bmp" />
            <local:ImageFavorite ImageId="6" ImageName="Not Ripe" ImageRating="5" ImageHref="Images/cheeznotripe.bmp" />
            <local:ImageFavorite ImageId="7" ImageName="Kibbles" ImageRating="3" ImageHref="Images/kibbles.bmp" />
            <local:ImageFavorite ImageId="8" ImageName="Commuting" ImageRating="2" ImageHref="Images/failcommute.bmp" />
            <local:ImageFavorite ImageId="9" ImageName="Huh?" ImageRating="5" ImageHref="Images/huhfail.bmp" />
            <local:ImageFavorite ImageId="10" ImageName="Bubble Gum" ImageRating="5" ImageHref="Images/bubblegum.bmp" />
        </x:Array>
    </Window.Resources>

    This data can now be used in this XAML window.  To access this data, for example, if using a list box control you can assign the ItemsSource="{StaticResource FavoriteImages}" where FavoriteImages is the key assigned to the array of objects in the Resources.  The data defined in resources will now render at run-time in the list box control.

    October 16

    MSDN Developer's Conference Announced

    There's another conference that will allow you to benefit from some of the content that is being presented at PDC.  So if you missed out on PDC you won't want to miss out on this.  The conference will be hosted in 12 cities across the U.S. between December '08 and February '09.  The URL for the conference is http://www.msdndevcon.com , also follow the conference on twitter at @msdndevcon.

    There is going to be 12 sessions available in 3 tracks, they are:

    Track 1 - Cloud Services

      • A Lap Around Cloud Services
      • Developing and Deploying Your First Cloud Services
      • Live Services: A Lap Around the Live Framework and Mesh Services
      • Developing Applications Using Data Services

    Track 2 - Client and Presentation

      • Windows Presentation Framework (WPF) Roadmap No. 4.0
      • Developing Data-centric Applications Using the WPF DataGrid and Ribbon Controls
      • Building Business-Focused Applications using Silverlight 2
      • ASP.NET 4.0 Roadmap

    Track 3 - Tools, Language and Framework

      • The Future of Managed Languages: F#, C#, and Visual Basic
      • A Lap Around "Oslo"
      • "Rosario": A Sprint with the Next Version of Microsoft Visual Studio Team System
      • Parallel Programming for Managed Code Developers

    Best of all there will be Open Spaces at this conference where you can go and network and get your questions answered, most likely the speakers of the sessions will be corralled here when they are not speaking.

    October 14

    Silverlight 2 - Released

    Today Silverlight 2 was released, let the excitement start!  Here are the resources that you'll need to get going:

    Silverlight Tools for Visual Studio 2008 SP1 Release Candidate 1

    Service Pack 1 for Expression Blend 2

    Deep Zoom Composer

    Still waiting on the drop for the Silverlight Dynamic Languages SDK, but I'm sure it'll happen soon :-)  Once that happens I'll be updating the previous IronRuby demos for the release version of Silverlight 2.

    If you are an Eclipse IDE user, you can find Eclipse tools for Silverlight here.

    Go forth and Light Up The Web !

    Updated: through the powers of twitter @jschementi lets us know that the Silverlight Dynamic Languages SDK is to be released tomorrow :-)

    10/16/2008 - Dynamic Silverlight SDK Released for Silverlight 2 available here: http://www.codeplex.com/sdlsdk/Release/ProjectReleases.aspx?ReleaseId=17839 

    September 18

    Dynamically Creating Path Data in Silverlight 2

    Recently I started playing around with the creation of a Silverlight application of C#; leaving my comfort zone of doing Silverlight development solely in IronRuby.  The project that I decided to start is an application that is similar to the famous "Wheel of Lunch", which will essentially query the Windows Live Search phonebook web service for any number of criteria (I am not limiting it to places to eat, you can choose to search hardware stores if you'd like), and have it populate what I am now calling the "Wheel of Choice" with the search results, it will then allow the user to spin the wheel, and the app will provide the user with their choice.

    My adventure with Silverlight paths started as I was trying to figure out how to render the wheel.  I wanted to keep this Silverlight user control as flexible as possible, so that I could easily use it in other projects.  The requirements that I put forth were:

    • the wheel size must be customizable
    • the wheel must be able to be split into any number of sections
    • the sections of the wheel must be rendered to be of equal size
    • each section must be labeled with text passed in to the control(to represent a choice)

    It was necessary to generate each section of the wheel separately, so that each section could be it's own element.  The Path element is the most flexible solution, it's Data attribute essentially contains instructions on where to draw random lines and curves on the canvas.  Looking at Path data can be daunting, it looks like a bunch of letters and numbers concatenated together, and to the blind eye, it really does not tell you a whole lot (example: "M 10100 C 10300 300,-200 250100z"). 

    In doing a little research I found out that the data string is made up of a Path sub-language, I find it similar to the old Turtle graphics programs, only it's definitely made for grown-ups.  A reference to the Path syntax is found here.  While I completely understand that you can make up a path's data by using a bunch of geometry elements,  I wanted more of a challenge so I decided to dynamically build the paths for each section using the Path syntax.

    The control was created with two public properties:

    public double Radius { get; set; }
    public List<string> SectionLabels { get; set; }

    Radius takes care of the overall size of the wheel, and SectionLabel defines the tool tip to set on each section (as well as defines the number of sections needed on the wheel).  Some private properties are also used to be used globally throughout the user control:

    private int _sectionCount { get; set; }
    private double _theta { get; set; }
    private Color[] _colors = { Colors.Red, Colors.Green, Colors.Blue, Colors.Yellow, Colors.Orange };

    _sectionCount places the total number of sections in a value type, just so that it's not necessary to keep pulling the SectionLabels.Count property. _theta is the angle that is used to identify endpoints on the edge of the wheel.  _colors is an array used to assign a color to each section created.  Setting of these values and the calculation of _theta is as follows:

    //calculates the number of sections to render as well as the theta value used to calculate the 
    //endpoints on the circle to render lines and arcs.
    private void Calculate()
    {
        _sectionCount = SectionLabels.Count;
        if (_sectionCount <= 0)
            _sectionCount = 1;
        _theta = 2 * Math.PI / _sectionCount;  
    }

    As specified before, _theta is used to find the evenly-spaced endpoints around the circle which will make up the sections.  The method to calculate these endpoints is as follows (where section is simply the index of the section being rendered):

    private Point calculateCircleEndPoint(int section)
    {
       double x = (Radius * (Math.Cos(section * _theta))) + Radius; 
       double y = (Radius * (Math.Sin(section * _theta)))+ Radius;
       return new Point(x, y);
    }

    Putting it all together, the RenderWheel() public method takes care of calculating the endpoints as well as defining the Path.  The first lesson learned is that you cannot directly assign the generated path data string to a Path's data attribute, it must be of type Geometry.  To get around this issue, the XAML for the path is instead generated with the string value in the data attribute, then cast back into a Path element and then added to the visual root of the user control. Do not forget to include the namespaces in this generated XAML.  The well-commented listing of the RenderWheel method is as follows:

    public void RenderWheel()
    {
        Calculate();
     
        //a point in the center of the circle
        Point circleCenter = new Point(Radius, Radius);
     
        //array to hold evenly spaced endpoints on the circle
        Point[] circlePoints = new Point[_sectionCount];
     
        //calculate the evenly-spaced points on the edge of the circle
        for (int i = 0; i < _sectionCount; i++)
        {
            circlePoints[i] = calculateCircleEndPoint(i);
        }
     
        int colorIndex = 0;
     
        //build out the path representing each segment
        for (int i = 0; i < _sectionCount; i++)
        {
            StringBuilder pathData = new StringBuilder();
            //move to circle center
            pathData.Append("M ");
            pathData.Append(circleCenter.ToString());
            //draw line to edge of circle, to the first calculated endpoint
            pathData.Append(" L ");
            pathData.Append(circlePoints[i].ToString());
            //draw an arc 45 degrees to the next circle end point 
            //(or the first calculated point if it is the last drawn segment)
            pathData.Append(" A ");
            pathData.Append(circleCenter.ToString());
            pathData.Append(" 45 0 1 ");
            int check = i + 1;
            if (check == _sectionCount)
                check = 0;
            pathData.Append(circlePoints[check].ToString());
            //close the section shape (renders line back to the center point)
            pathData.Append(" Z ");
     
            //Cannot add string path directly to Data property, so it must be injected, also inserts tool tip xaml
            string sectionTip = "<ToolTipService.ToolTip><ToolTip Content=\"" + SectionLabels[i] + "\"/></ToolTipService.ToolTip>";
            string nsPath = "<Path xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\" xmlns:x=\"http://schemas.microsoft.com/winfx/2006/xaml\" Data=\"";
            Path section = (Path)XamlReader.Load(nsPath + pathData.ToString() + "\" x:Name=\"sect"+ i +"\">"+ sectionTip +"</Path>"); 
            section.Stroke = new SolidColorBrush(Colors.Black);
            section.StrokeThickness = 0.3;
     
            //color the newly created section
            section.Fill = new SolidColorBrush(_colors[colorIndex]);
            if (colorIndex + 1 == _colors.Length)
                colorIndex = 0;
            else
                colorIndex++;
            
            //add filled path
            this.splitWheelRoot.Children.Add(section);
        }
     
    }

    For sake of completeness, here is the XAML of the user control (only an empty canvas):

    <UserControl x:Class="LiveSearch.SplitWheel"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
        >
        <Canvas x:Name="splitWheelRoot">
            
     
        </Canvas>
    </UserControl>

    The complete code-behind for this control can be found here . The final result (though not very pretty) looks like this:

    wheel

    August 12

    IronRuby Resources

    This is a blog post that will be updated over time.  It's intention is to collect the best IronRuby resources on the web, so feel free to leave a comment and let me know of additional resources you would like to see listed here.

    Specific IronRuby related links:

    Inspired By

    I was tagged by Josh Holmes in his Inspired By blog post.  My reply to this tag is a long time coming.  This is due to the fact that there is just so many people in the developer community that truly inspire me.

    I am inspired by people that give back to the developer community.  The people that openly share experiences and make it a point to improve the knowledge of fellow developers.  These people take time out to genuinely help people reach their goals in their career, they also help feed the curiosity for them to try new things in technology.  These people are (in no particular order):

    • Bloggers - who openly share their development experiences with others, so that they may avoid similar pitfalls, solve problems and apply techniques/technologies that are successful in their problem-space.
    • Screencasters - who show hands-on exactly how their technology of choice can be applied visually.  The benefits of this is that a single screencast can be created once and be reachable to any developer.
    • Speakers/Presenters - who spend countless hours and sleepless nights perfecting the delivery of a session that will help developers understand and apply the topic at hand.
    • Event Organizers - who also spend countless hours and sleepless nights crossing the T's and dotting the i's to ensure event attendees are provided a comfortable and functional learning environment.  They also organize the marketing, speakers and sponsorship so that the event is possible in the first place.
    • Event Volunteers - usually the people "behind the curtain" ; they work feverishly throughout the event to ensure the event plans are executed without a hitch and help attendees wherever needed.
    • Event Attendees - the most important piece of the developer community.  These are the people who show ambition and desire to learn and improve their trade.  They go back to their workplace and lead by example; taking the lessons they have learned and apply the technologies in successful ways (and most importantly share the information with others).  These are the people that make the developer community worthwhile.

    I know it seems as if I'm dodging the question of who it is that inspires me, so I'll spill it.  The first person that had a profound impact on my interest in the developer community is Drew Robbins.  I met Drew at a Developer Days event in November 2001.  He was actively recruiting members for the Central Ohio .Net Developer's Group here in Columbus Ohio.  Let's just say that some day I would hope to match the passion that he has for the developer community.  He is the person who encouraged me to get more involved, to get over any fears and just get out there and make a difference.

    July 18

    Ann Arbor Give Camp - Columbus Mirror (July 12th and 13th)

     

    The Ann Arbor Give Camp is a coding for charity event organized by Jennifer Marsman, Patrick Steele, John Hopkins, Todd Bohlen, Bill Wagner, and Kristina Jones.  Essentially it's an event that allows software developers and designers to join forces to develop software and websites for charitable organizations.  In all 15 charities were helped.

    The weekend started for me on Friday afternoon.  I decided it would be beneficial to meet the charity the Columbus group was to support in person.  So I packed up (with my youngest child) and headed out to Ann Arbor, and arrived as the Introductions of the charities were taking place.  I was able to meet the charity, find out their passions, and learn what their expectations for a new website were.  I took this information back to Columbus (not arriving home until after 2am). 

    Woke up early on Saturday morning and arrived to meet the other volunteers at the Microsoft Offices in Columbus at 8:30am.  We all worked well as a team and ultimately started project roles, design and coding very quickly.  The day ended Saturday at about 10:30pm.  I decided to head home and continue coding as bandwidth was an issue at the offices, and took advantage of the broadband at home until about 1:30am.  We all regrouped about 8:30am on Sunday morning and pushed forth until we wrapped things up around 6pm.

    Lessons learned are, have fun, no matter what, collaborate as much as you can, listen and learn from others, and sleep really isn't necessary :) ... For future events, I think it would be beneficial to get the requirements at least a week ahead of time, and identify project roles before the marathon design/coding begins.

    Pictures of the event

    I have nothing but high praises for all the volunteers that came out to make the event a success.  Everyone worked extremely hard, and constant (we didn't use the break lounge once).  The room was very quiet at times due to the amount of code throughput.  Regardless, everyone was in good humor the entire weekend and we all had a blast!

    The Columbus Mirror Give Camp Volunteers were:

    July 03

    Happy Contribupendence Day!

    This blog post is in response to Contribupendence Day as created by Jeff Blankenburg at Microsoft.  The idea behind Contribupendence day is to acknowledge 5 people you know that are respected, appreciated and talented and provide them with internet recommendations.  I chose LinkedIn as my social network conduit (only joining it last night).  The 5 people I chose are (in first name alpha order):

    James Bender

    "James is very exemplary in his knowledge of technology. I have seeked out his expertise (primarily surrounding WCF) when dealing with technical problems that I encounter in my work. James is always willing to contribute ideas and solutions, because of this he is very respected in the developer community"

    Jennifer Marsman

    "Jennifer has an infectious good energy surrounding technology. She is very motivated and always willing to go the extra mile. She is motivated by helping people and organizations to reach their goals. Jennifer is also an advocate for Women in Technology, and as such is an inspiration to us all. She is one of the smartest people I know, and a pleasure to work with."

    Justin Kohnen

    "Justin is a very driven individual. He is also responsible for helping organizing very successful technical events. He is known in the community to step up to the plate, and is a very good technical speaker (presenter)"

    Matt Dinovo

    "Matt is a born leader and teacher. When I had the opportunity to work with him, he opened my eyes to the inner workings of ASP.Net and the future direction of the .Net platform. He mentored me on many practical and important patterns and best practices which has benefitted me greatly in my career and in the developer community. Since working with him I have had a passion for all things .Net and much of this is due to some of his enthusiasm for technology rubbing off on me."

    Michael Letterle

    "I am lucky to have to opportunity to be in contact with Michael. We share similar interests in the IronRuby project on which he contributes. His passion for technology is contagious, and his knowledge is admirable. I also like the fact that he keeps me on my toes with regards to running the newest drops of the IronRuby project. Keep up the good work Michael, I look forward to your presentation at eRubyCon!"

    June 15

    IronRuby, Silverlight, DeepZoom demos Updated for Silverlight 2 Beta 2

    You'll need to uninstall all Silverlight 2 Beta 1 tools, and install the Silverlight 2 Beta 2 Chainer (which includes tools for VS 2008, see www.silverlight.net)

    Then update your Silverlight Dynamic SDK.

    If you are doing Deep Zoom, get the new Deep Zoom Composer.

    Here are updated Demos:

    Demos 1 - 3

    IronRuby Deep Zoom Sample

    May 20

    IronRuby, Silverlight and Deep Zoom (Beta 1)

    This past weekend I had the honor of presenting my IronRuby, the DLR and Silverlight talk at Cleveland Day of .Net.  As promised I am posting the Deep Zoom sample that I had created. 

    One gotcha that you will hit is that during the development, you will be required to add the mime type for the *.bin extension in your chiron.exe.config file by default located at C:\Program Files\Microsoft SDKs\Silverlight\v2.0\Tools\Chiron, add <mimeMap fileExtension=".bin"  mimeType="application/x-binary"/> in the mimetypes section. 

    For the first three demos (gradient rectangle, mirror image, rotating text), access my previous blog post here

    You can download the Deep Zoom Composer here, remember to export as a composition, and if you are using IronRuby you need not bother with the Silverlight project.  Once the project is exported, copy the files exported to the assets folder of your Silverlight application.  Ensure the xaml of the MultiScaleImage element is pointing to the info.bin file of your composition.

    I am planning on putting together some screencasts that will step through applying IronRuby, as well as Silverlight (and Deep Zoom).  Stay tuned!

    Presentation Slides

    IronRuby/Deep Zoom Demo

    (first three demos are here: Prior Blog Post )

    *** Updated for Silverlight 2 Beta 2 Here ***

    April 27

    Euler Problem No.2 in IronRuby

    Each new term in the Fibonacci sequence is generated by adding the previous two terms. By starting with 1 and 2, the first 10 terms will be:

    1, 2, 3, 5, 8, 13, 21, 34, 55, 89, ...

    Find the sum of all the even-valued terms in the sequence which do not exceed four million.

    Here is my IronRuby solution (2 ways): or download it here

    image

    Euler Problem No.1 in IronRuby

    I came across a site that contains mathematical problems that can be solved programmatically.  The site is http://projecteuler.net .  I thought this was a good site to frequent so that I can learn how to apply my new found love for IronRuby.  Running this samples requires that you download and build IronRuby, I also added the location of rbx.exe to my Path environment variable.  To run this file type "rbx Euler1.rb" from a command prompt in the folder that contains your source file. 

    After solving the first problem from Project Euler, I am officially 1% genius :) Here is two solutions that I came up with: or download the file here 

    image

    April 25

    Getting Started With IronRuby, the DLR and Silverlight (Beta 1)

    Recently I presented this talk at the Central Ohio Day of .Net.  It was an excellent experience, the sessions were all top notch, and the attendees were great! I'm sure to do this again next year.  If you missed out, there are other Day of .Net events scheduled in nearby areas, to get a list, you can access the event schedules here.  Anyway, as promised, I said I would post my presentation material.  Keep in mind, to get started with IronRuby on Silverlight, you will need to download the "beta bytes" of Silverlight 2 Runtime, the Silverlight 2 SDK,as well as the Silverlight Dynamic SDK.  You will not be required to pull IronRuby from RubyForge because it is included in the Silverlight Dynamic SDK.  If you do decide to pull IronRuby to take a look at it's implementation, you will also need the full-fledged Ruby installed on your machine.  It is also recommended that you include the folder that contains Chiron.exe into your path.  To run the demos, run in the root folder from the command prompt "Chiron \b", this will run chiron and open internet explorer with your IronRuby/Silverlight program loaded, click on "index.html" to run the demo.  Future blog posts will share IronRuby concepts in further detail, stay tuned!

    Presentation Slides (sorry, forgot the war kittens)

    Demo Code

    (Demo1 - Rounded/gradient rectangle, Demo 2 - Mirror image, Demo 3 - spinning text)

    ** Updated For Silverlight 2 Beta 2 Here **

    December 13

    What makes a successful project ?

    In short a successful project is dependent on a successful team. 

    Project team members need enthusiasm, commitment, and excitement in the final product.  The team must be able to work cohesively, constantly challenging themselves to meet milestones and helping people out when they run into trouble.  Some ideas to achieve this "glory team" would be to Recognize achievement, Encourage the support of other team mates, Challenge people in a fun but competitive way, and Reward people for a job well done. 

    A project team blog is a wonderful idea, there could be one main Blog for the project as a whole to communicate status and the overall well-being of the project, each member should then have their own sub-blogs where they can post issues they have run into with their solutions, how they have assisted other people, and overall little tid-bits of interesting things that they have learned.  These blogs later on can serve as a sort of knowledge base, that is searchable and thus helps share the tribal knowledge.

    Another good idea is to reward people for working as a team.  On the project blog, set out daily or weekly challenges to the project team, challenge them to Assist a Teammate and post a comment about this, or a challenge to post the most useful thing that they learned that week, and so on and so forth.  Randomly select a winner in each of these challenges and present them with small trinkets of swag and recognition of a job well done.

    November 10

    Why are some people's blog posts so long ??

    This entry is really two-fold... It's been a while since I posted to my own blog, but I have been reading certain other people's blogs regularly.  I do enjoy the small quick entries, and the middle of the road detailed blog post, BUT... OMG... what's with the 30 printed pages blog entries ?  Maybe those should be submitted to book publishers *LOL* ! 

    Anyways, I am trying out this Live Writer product for the first time (yes, I am behind the times).  Editing medium to large blog posts is not really what a web interface is built for.  Also, it's convenient to compose blog posts while on the go, and not necessarily connected to the web at all times.  So let's see how easy this thing is to use, so far so good... now let me click the publish button.....