| Carey's profilemoved to www.codingbandi...PhotosBlogLists | Help |
|
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; elsedataTemplate = pres.FindResource("SimpleTemplate") as DataTemplate; return dataTemplate;} } } xmlns:local="clr-namespace:TemplateSelector" <local:RatedImageTemplateSelector x:Key="RatedImageTemplateSelector" /> <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: 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> <ListBox x:Name="lbResults" Grid.Row="1" Grid.Column="0" Height="240" HorizontalContentAlignment="Stretch" ItemsSource="{StaticResource FavoriteImages}" ItemTemplate="{StaticResource SimpleTemplate}" /> <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" /> private void btnDetail_Click(object sender, RoutedEventArgs e) { //pull the detailed template from resources, identified by the DetailedTemplate keyDataTemplate 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 keyDataTemplate summary = this.FindResource("SimpleTemplate") as DataTemplate; lbResults.ItemTemplate = summary; } Summary Template: Detailed Template: Full source code for this sample is available here. November 02 WPF Data Templates Part 2 - Value ConvertersSometimes 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 Memberspublic object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) { //in order to handle design time problems, handle null value caseif (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" /> <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. Complete source code for this sample is available here. November 01 WPF Data Templates Part 1 - Introduction to WPF Data TemplatesLook 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 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 WPFIf 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}" /> Source code for this plain list box is available here. A Simple Data TemplateWhile 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> 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> Sample code for the previous two examples is available here. Defining your Objects with XAML in Resources to enhance your Design Time ExperienceXAML 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
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 AnnouncedThere'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
Track 2 - Client and Presentation
Track 3 - Tools, Language and Framework
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 - ReleasedToday 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 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 2Recently 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:
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 circlefor (int i = 0; i < _sectionCount; i++) {circlePoints[i] = calculateCircleEndPoint(i); } int colorIndex = 0; //build out the path representing each segmentfor (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 xamlstring 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; elsecolorIndex++; //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: August 12 IronRuby ResourcesThis 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 ByI 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):
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. 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 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 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 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 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." "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 2You'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: 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! (first three demos are here: Prior Blog Post ) April 27 Euler Problem No.2 in IronRubyEach 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 Euler Problem No.1 in IronRubyI 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 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) (Demo1 - Rounded/gradient rectangle, Demo 2 - Mirror image, Demo 3 - spinning text) 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..... |
|
|