If you use Visual Studio often, you probably pinned it to the task bar so you can quickly access it. Here is a tip for opening Visual Studio from the task bar using the keyboard.
First, count the position of Visual Studio in the task bar. Mine is in position #10.

Hold down the Windows Key + Alt + # of the item. On my system, this is Windows Key + Alt + 10. Then use the arrow keys to select the desired project.

Use this technique any time you want to launch Visual Studio from the Task Bar using the keyboard.
Enjoy!
You can open Visual Studio multiple times, but each environment has the same settings. With Visual Studio 2010 and experimental instances, you can now have entirely different instances of Visual Studio with different settings.
If you open up Visual Studio 2010 and make the font larger or install specific extensions, those settings are used every time you open Visual Studio. This assumes that you want to work with Visual Studio the same way every time you use it. But you may have scenarios where this is not the case.
Say you want to set up your Visual Studio with one set of settings for your daily work and a different set when you do demos to your team or user group. Or you want one set of settings when you work on an ASP.NET application and a different set when you work on Windows Forms. Or one set when you work with client x and another set when you work with client y.
To support these scenarios, Visual Studio 2010 provides a feature called "experimental instances". Experimental instances allow you to set up multiple instances of Visual Studio with completely different settings, options, and extensions.
To set up an experimental instance, create a short cut to Visual Studio. Include with the path, the option /RootSuffix XXX, where XXX is any name you want to give to your alternate instance.
For example:
"C:\Program Files (x86)\Microsoft Visual Studio 10.0\Common7\IDE\devenv.exe" /RootSuffix Demo
This sets up a new instance of Visual Studio called Demo. You can create any number of these new instances, just give them unique names.
The following is a screen shot for my demo instance:

Use this technique any time you want to set up multiple instances of Visual Studio.
Enjoy!
The Visual Studio Live! (VSLive!) conference is coming to Redmond next week. I am really looking forward to a week of learning, connecting with other developers, and just having some fun.
The code for my two session is available at the following links:
Hope to see you there!
The Silicon Valley Code Camp was last week-end and was again a GREAT event. We had close to 2200 attendees and lots of fun.
My presentation was on "Best Kept Secrets in Visual Studio 2010 and .NET 4.0". It covered lots of the little things inside Visual Studio, the languages, and the framework that are lesser known hidden gems. You can find the code for the presentation here.
Enjoy!
I am presenting "Microsoft Silverlight, WCF RIA Services, and Your Business Objects" at the Tech Ed 2011 conference in Atlanta on May 18, 2011.
You can get the code for my talk from my company's Web site. Look for the Tech Ed 2011 entry.
If you are at Tech Ed, come by and say hi. I will be at the Silverlight booth on Monday night and on Wednesday afternoon.
Enjoy!
Data annotation attributes are a great way to add single property validation to your Silverlight/WCF RIA application. But what if you don't want to inject attributes all over your business classes? The purpose of a metadata class is to have a place for all of these attributes external from the business class.
NOTE: This post is part of a set of validation posts which starts here and it uses the sample code from this prior post.
If your Silverlight application uses WCF RIA services and your own business objects, then you can set attributes on your business object properties to define single-attribute validation.
In this prior post, the code example demonstrated how to use the single property validation attributes available to validate that a last name is entered and does not exceed 20 characters, the attributes look like this:
[Required(ErrorMessage = "Please enter a last or family name.")]
[StringLength(20, ErrorMessage = "Last name cannot exceed 20 characters.")]
public string LastName { get; set; }
If you don't want these attributes in your business classes, you can instead create a metadata file and store all of the attributes there.
1) Right-click on your business object's Class Library project and add a new class (Add | New Item | Class).
In this example, the class was called Student. So the metadata class is named StudentMetadata.cs.
2) In this new class, add any of the business object properties and associated attributes.
Note that the property names defined in the metadata class must exactly match the property names in the original class.
In C#:
using System.ComponentModel.DataAnnotations;
namespace InStepValidationExample.BL
{
internal sealed class StudentMetadata
{
/// <summary>
/// Private to ensure this class is not instantiated.
/// </summary>
private StudentMetadata()
{}
[Required(ErrorMessage = "Please enter a last or family name.")]
[StringLength(20, ErrorMessage = "Last name cannot exceed 20 characters.")]
public string LastName { get; set; }
}
}
In VB:
TBD
3) Associate the metadata class with its original class using a MetadataType attribute on the original class definition. This attribute associates the original business object class with the metadata class.
In C#:
namespace InStepValidationExample.BL
{
[MetadataType(typeof(StudentMetadata))]
public class Student
{
...
}
}
In VB:
TBD
When you run the application, the validation should work as before:

Use this technique any time you want attributes on your business object properties, but want to define these attributes external from the business object classes.
Enjoy!
Resource files are a great way to manage strings, especially if you need to support multiple languages. This post demonstrates how to use a resource file with the validation attributes used by Silverlight and WCF RIA Services.
NOTE: This post is part of a set of validation posts which starts here and it uses the sample code from this prior post.
In this prior post, the code example demonstrated how to use the single property validation attributes available in Silverlight and WCF RIA Services. For example, to validate that a first name is entered and does not exceed 20 characters, the attributes look like this:
[Required(ErrorMessage="Please enter a first name.")]
[StringLength(20, ErrorMessage = "First name cannot exceed 20 characters.")]
public string FirstName { get; set; }
Notice how the validation error messages are hard-coded strings. This poses a challenge if you need to localize your application.
A better option is to add the strings to a resource file. The trick here is that the resource file needs to exist both on the server (in the Class Library project if you are using WCF RIA with your own business layer) and on the client (in the Silverlight project). This is done by a process called linking.
1) In the Class Library project containing your business layer, add a resource file (Add | New Item | Resources File).
I added mine to a Resources folder in the project.
NOTE: If you are not using your own business layer on the server, you can add the resource file directly to the Web project instead.
2) Enter a name for each string along with the string values. Optionally add a comment.
3) Set the Access Modifier for each resource string to Public.
The result should look something like this:

4) In the Silverlight project, link to that resource file by selecting Add | Existing Item and then clicking on Add As Link in the Add Existing Item dialog.

5) In the Silverlight project, link also to the associated Designer.cs file.
NOTE: The Add Existing Item dialog allows multiple selection. So you could link both the rex file and the Designer/cs file in one step.
6) Modify the attribute parameters in the business layer Class Library project to reference the resource file instead of using hard-coded strings. Be sure to add a using for the resource file's namespace:
using InStepValidationExample.BL.Resources;
[Required(ErrorMessageResourceType = typeof(ValidationErrorResources),
ErrorMessageResourceName = "FirstNameRequired")]
[StringLength(20,
ErrorMessageResourceName = "FirstNameLength",
ErrorMessageResourceType = typeof(ValidationErrorResources))]
public string FirstName { get; set; }
Instead of setting the ErrorMessage parameter to a hard-coded string, this code sets the ErrorMessageResourceType parameter to the type of the resource file (which is the resource file name). The ErrorMessageResourceName parameter specifies the name that you defined for the associated resource string in the resource file.
7) Now for the tricky part. By default, Visual Studio requires that the two resource files be in the same namespace. If they aren't, the application won't find the resources.
For example, if you use the Silverlight Business Application template, you can see that it puts the resource file in the BizApp.Web project under a Resources folder. The resources are then in the BizApp.Web.Resources namespace.
To access the resources from the BizApp Silverlight project, the file is put in a folder hierarchy with a Web folder and then a Resources folder so the resulting namespace is again BizApp.Web.Resources.

In the example for this post, however, the resources are in a Class Library in a business layer separate from the Web project:

The namespace of the resources in the business layer is InStepValidationExample.BL.Resources. The namespace of the resources in the Silverlight project is InStepValidatoinExample.SL.Resources.
So if you run the application at this point, it will crash with a "TargetInvocationException occurred" message. If you look at the exception detail it says "Could not find any resources appropriate for the specified culture or the neutral culture..." Basically, it cannot find the resource file.
Luckily, we know the secret handshake required to get this to work:
7a) Right-click on the Silverlight project and select Unload Project.
7b) Right-click on the Silverlight project again and select to edit the project file.
7c) Add a <LogicalName> element to the <EmbeddedResource> element in the project file and set it to the namespace and resource name. Mine looked like this:
<ItemGroup>
<EmbeddedResource Include="..\InStepValidationExample.BL\Resources\ValidationErrorResources.resx">
<Link>Resources\ValidationErrorResources.resx</Link>
<LogicalName>
InStepValidationExample.BL.Resources.ValidationErrorResources.resources
</LogicalName>
</EmbeddedResource>
</ItemGroup>
7d) Close the project file.
7e) Right-click on the Silverlight project and select Reload Project.
Now when you run, it should find your resource file.

Use a resource file any time you want better management of your strings, especially if you plan to localize your application.
Enjoy!
When you identify the validation scenarios for your application, you will find that some only require basic single property validation. Examples:
- Ensure that a first name is entered.
- Ensure that the first name is not longer than 20 characters
- Ensure that the age is between 16 and 120.
- Ensure that the email address is valid.
NOTE: This post is part of a set of validation posts which starts here and it uses the sample code from this prior post.
Each of these requirements can be handled by Silverlight's single field validation using property attributes.
When you use WCF RIA Services and your own set of business objects, these attributes are set in the business layer on the business object properties. WCF RIA Services then automatically generates a copy of your business object properties with their attributes on the client for use with Silverlight.
Silverlight performs the validation when the user leaves the field AND before the data is submitted to the server. If there is a validation error, the data is not submitted to the server and a validation error appears.
Each of the simple validation attributes are discussed below.
Required Field Validation
Use the Required attribute to mark a property as required. For example, if the first name is required, the first name property is adorned as follows:
[Required()]
public string FirstName { get; set; }
If you make this change and run the sample application (from this prior post), the first name field is automatically validated. Clear the field and you will see this:

Silverlight's built-in validation automatically kicks in and you see the default required validation error message.
NOTE: You can modify the Silverlight XAML to specify the ValidatesOnNotifyDataErrors property as part of the binding expression. However, this is not necessary. The default value of this property is true, so the validation errors are reported by default.
If you don't like the error message, you can change it by setting one of the named parameters of the Required attribute:
[Required(ErrorMessage="Please enter a first name.")]
public string FirstName { get; set; }
The message then appears as shown below:

Use required field validation any time you want to ensure that the user enters a value into a Silverlight control.
String Length Validation
Often times the data entered on a page in Silverlight will get stored to a database where a maximum field size is defined. It is helpful for the users to be aware of this maximum before attempting to submit the data to the server.
For example, if the first name is set to a maximum of 20 characters in the database, you can set the StringLength attribute as follows:
[Required(ErrorMessage="Please enter a first name.")]
[StringLength(20, ErrorMessage = "First name cannot exceed 20 characters.")]
public string FirstName { get; set; }
Use string length validation any time you want to ensure that the user does not enter more data than can be stored in the database table or any other time that a string length cannot exceed a maximum value.
Range Validation
When entering numbers, often times the value must be limited to a specific range of values. For example, in this application the age must be between 16 and 120.
[Range(16, 120,
ErrorMessage="Please enter your age. You must be 16 or older.")]
public int Age { get; set; }
This results in the following:

NOTE: The Range attribute has overloads with parameters that are integers or doubles. To validate other types (such as decimal), you need to use the Range overload that takes a type as the first parameter and string values to convert to the defined type. For example:
[Range(typeof(Decimal),"0", "40000")]
public decimal TuitionPaid{ get; set; }
Use range validation any time you want to validate user entry to a range of numeric values.
Regular Expression Validation
Regular expression validation allows you to perform pattern matching on the entered value. For example, an email address must match a specific pattern with a local part of the address followed by an at sign (@) followed by a domain name. The Regular Expression attribute could look like this:
[Regular(@"^(?("")("".+?""@)|" +
@"(([0-9a-zA-Z]((\.(?!\.))|" +
@"[-!#\$%&'\*\+/=\?\^`\{\}\|~\w])*)(?<=[0-9a-zA-Z])@))" +
@"(?(\[)(\[(\d{1,3}\.){3}\d{1,3}\])|" +
@"(([0-9a-zA-Z][-\w]*[0-9a-zA-Z]\.)+[a-zA-Z]{2,6}))$",
ErrorMessage="Please enter a valid email address")]
public string Email { get; set; }
NOTE: Replace "Regular" above with "RegularExpression". For whatever reason, the entire string was blocked in this post if the word "Expression" appeared above.
Other properties that could use a regular expression include phone numbers, social security numbers, and any other entry that must match a specific pattern.
You can find more information on regular expressions here.
Use regular expressions any time you want to validate a user's entry based on pattern matching.
For more complex validation scenarios, see this prior post.
Enjoy!
EDIT 5/2/11: Corrected typographical errors. Corrected the regular expression, which did not paste into the post correctly.
This post provides a simple Silverlight MVVM, WCF RIA Services sample application that is used to demonstrate validation techniques. The sample application is provided in this separate post so it can be readily used with any of the presented validation techniques.
NOTE: This post defines a sample application that is used in the validation scenarios presented in this prior post.
The application is a simple data entry form for entering basic student information.

To create this application, follow these steps.
1) Build four projects:
- C# or VB Class Library project defining the business layer. (This is NOT a Silverlight class library.)
- C# or VB Silverlight Application project. (Be sure to check the Enable WCF RIA Services checkbox.)
- C# or VB ASP.NET Web project. (This project is automatically created when creating the Silverlight Application project).
- C# or VB Silverlight Class Library project. (For the library functions, such as commanding.)
2) In the first Class Library project (the one that is NOT a Silverlight class library), build a Student business object.
In C#:
using System;
using System.ComponentModel.DataAnnotations;
using System.Diagnostics;
namespace InStepValidationExample.BL
{
public class Student
{
public int Age { get; set; }
public string Email { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public DateTime? RegistrationDate { get; set; }
[KeyAttribute]
public int StudentId { get; set; }
public DateTime? VaccinationDate { get; set; }
public bool? VaccinationOptOut { get; set; }
public static Student Retrieve(int id)
{
var student = new Student
{
StudentId = id,
LastName = "Baggins",
FirstName = "Bilbo",
Age = 111,
Email = testemail@live.com,
VaccinationOptOut = true,
RegistrationDate = DateTime.Now
};
return student;
}
public bool Save()
{
// Code that saves the changes to the database;
Debug.WriteLine("Saving: " + LastName + ", " + FirstName);
return true;
}
}
}
In VB:
TBD
This code defines a set of simple properties for a student. The StudentId property is marked with the KeyAttribute, which defines a unique Id for the entity. This attribute is required for this entity to work with WCF RIA Services.
The Retrieve and Save methods in this example are "fake" methods. You would need to replace the code in these methods with code to retrieve and save the student from a data store such as a database. By using the fake code for this, you can try out the validation techniques without needing to build or access a database.
3) In the ASP.NET Web application, build a Student Domain Service class.
In C#:
namespace InStepValidationExample.SL.Web
{
using System.ServiceModel.DomainServices.Hosting;
using System.ServiceModel.DomainServices.Server;
using InStepValidationExample.BL;
[EnableClientAccess()]
public class StudentService : DomainService
{
public Student GetStudentById(int id)
{
return Student.Retrieve(id);
}
public void UpdateStudent(Student student)
{
}
protected override bool PersistChangeSet()
{
Student changedStudent;
bool success = true;
foreach (var item in ChangeSet.ChangeSetEntries)
{
if (item.Entity.GetType() == typeof(Student))
{
changedStudent = (Student)item.Entity;
success = changedStudent.Save();
if (!success)
break;
}
}
return success;
}
}
}
In VB:
TBD
This code provides the following methods:
- GetStudentById to get the student from the business layer.
- UpdateStudent method to enable updating of the student.
- PersistChangeSet method to parse through the changeSet and save any changed students.
You can add Insert and Delete methods as desired.
4) Build an MVVM base class in the Silverlight project as demonstrated in this prior post.
5) Build a Commanding class in the Silverlight Class Library project as demonstrated in this prior post.
6) Build the ViewModel in the Silverlight Application project.
In C#:
using System;
using System.Linq;
using System.ServiceModel.DomainServices.Client;
using System.Windows.Input;
using InStepValidationExample.BL;
using InStepValidationExample.Library;
using InStepValidationExample.SL.Web;
namespace InStepValidationExample.SL.ViewModels
{
public class StudentsViewModel : ViewModelBase
{
private StudentContext StudentContextInstance;
private ICommand _CancelCommand;
public ICommand CancelCommand
{
get
{
return _CancelCommand;
}
}
private Student _CurrentStudent;
public Student CurrentStudent
{
get
{
return _CurrentStudent;
}
set
{
if (_CurrentStudent != value)
{
_CurrentStudent = value;
OnPropertyChanged("CurrentStudent");
}
}
}
private ICommand _SaveCommand;
public ICommand SaveCommand
{
get
{
return _SaveCommand;
}
}
public StudentsViewModel()
{
LoadData();
DefineCommands();
}
private void DefineCommands()
{
_CancelCommand = new DelegateCommand<Object>
(OnCancelCommand);
_SaveCommand = new DelegateCommand<Object>
(OnSaveCommand);
}
/// <summary>
/// Loads the data for the application.
/// </summary>
private void LoadData()
{
if (IsInDesignModeStatic)
{
LoadDesignData();
}
else
{
// Load the student data asynchronously
StudentContextInstance = new StudentContext();
var loadop = StudentContextInstance.Load
(StudentContextInstance.
GetStudentByIdQuery(1),
OnStudentLoaded, null);
}
}
/// <summary>
/// Loads temporary data for use in the designer.
/// </summary>
/// <remarks></remarks>
private void LoadDesignData()
{
//Design mode data
var student = new Student
{
LastName = "Baggins",
FirstName = "Bilbo",
Age = 111,
Email = "testemail@live.com",
VaccinationOptOut = true,
RegistrationDate = DateTime.Now
};
CurrentStudent = student;
}
private void OnCancelCommand(object o)
{
StudentContextInstance.RejectChanges();
}
private void OnStudentLoaded(LoadOperation lo)
{
CurrentStudent =
StudentContextInstance.Students.FirstOrDefault();
}
private void OnSaveCommand(object o)
{
StudentContextInstance.SubmitChanges(OnChangesSubmitted,
null);
}
private void OnChangesSubmitted(SubmitOperation so)
{
if (so.HasError)
{
so.MarkErrorAsHandled();
}
}
}
}
In VB:
TBD
This code defines two commands: Save and Cancel. It then loads design-time data or at run-time it calls the GetStudentById query to retrieve the student from the business layer.
The OnChangesSubmitted code ensures that any validation errors are correctly marked as handled and don't cause an unhandled exception in your application (error 4004).
7) Build the View.
<UserControl x:Class="InStepValidationExample.SL.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="400"
xmlns:sdk="http://schemas.microsoft.com/winfx/2006/xaml/presentation/sdk"
xmlns:vms="clr-namespace:InStepValidationExample.SL.ViewModels">
<UserControl.DataContext>
<vms:StudentsViewModel />
</UserControl.DataContext>
<Grid x:Name="LayoutRoot"
Margin="2">
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid HorizontalAlignment="Center"
VerticalAlignment="Top"
DataContext="{Binding CurrentStudent}"
Margin="10">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<sdk:Label Content="First Name:"
Grid.Column="0"
Grid.Row="0"
HorizontalAlignment="Left"
Margin="3"
VerticalAlignment="Center" />
<TextBox Grid.Column="1"
Grid.Row="0"
Height="23"
HorizontalAlignment="Left"
Margin="3"
Name="firstNameTextBox"
Text="{Binding Path=FirstName,
Mode=TwoWay,
TargetNullValue=''}"
VerticalAlignment="Center"
Width="130" />
<sdk:Label Content="Last Name:"
Grid.Column="0"
Grid.Row="1"
HorizontalAlignment="Left"
Margin="3"
VerticalAlignment="Center" />
<TextBox Grid.Column="1"
Grid.Row="1"
Height="23"
HorizontalAlignment="Left"
Margin="3"
Name="lastNameTextBox"
Text="{Binding Path=LastName,
Mode=TwoWay,
TargetNullValue=''}"
VerticalAlignment="Center"
Width="130" />
<sdk:Label Content="Email:"
Grid.Column="0"
Grid.Row="2"
HorizontalAlignment="Left"
Margin="3"
VerticalAlignment="Center" />
<TextBox Grid.Column="1"
Grid.Row="2"
Height="23"
HorizontalAlignment="Left"
Margin="3"
Name="emailTextBox"
Text="{Binding Path=Email,
Mode=TwoWay,
TargetNullValue=''}"
VerticalAlignment="Center"
Width="130" />
<sdk:Label Content="Age:"
Grid.Column="0"
Grid.Row="3"
HorizontalAlignment="Left"
Margin="3"
VerticalAlignment="Center" />
<TextBox Grid.Column="1"
Grid.Row="3"
Height="23"
HorizontalAlignment="Left"
TextAlignment="Right"
Margin="3"
Text="{Binding Path=Age,
Mode=TwoWay,
TargetNullValue=''}"
VerticalAlignment="Center"
Width="130" />
<CheckBox Grid.Column="1"
Grid.Row="4"
IsChecked="{Binding VaccinationOptOut,
Mode=TwoWay,
TargetNullValue=false}"
Content="Vaccination Opt Out"/>
<sdk:Label Content="Vaccination Date:"
Grid.Column="0"
Grid.Row="5"
HorizontalAlignment="Left"
Margin="3"
VerticalAlignment="Center" />
<sdk:DatePicker Grid.Column="1"
Grid.Row="5"
Height="23"
HorizontalAlignment="Left"
Margin="3"
SelectedDate="{Binding Path=VaccinationDate,
Mode=TwoWay,
TargetNullValue=''}"
VerticalAlignment="Center"
Width="130" />
<sdk:Label Content="Registration Date:"
Grid.Column="0"
Grid.Row="6"
HorizontalAlignment="Left"
Margin="3"
VerticalAlignment="Center" />
<sdk:DatePicker Grid.Column="1"
Grid.Row="6"
Height="23"
HorizontalAlignment="Left"
Margin="3"
SelectedDate="{Binding Path=RegistrationDate,
Mode=TwoWay,
TargetNullValue=''}"
VerticalAlignment="Center"
Width="130" />
</Grid>
<StackPanel Grid.Row="1"
Orientation="Horizontal"
HorizontalAlignment="Right">
<Button x:Name="SaveButton"
Content="Save"
Command="{Binding SaveCommand}"
Width="75"
Height="24"
Margin="5"/>
<Button x:Name="CancelButton"
Content="Cancel"
Command="{Binding CancelCommand}"
Width="75"
Height="24"
Margin="5" />
</StackPanel>
</Grid>
</UserControl>
When you have the above code in place, you should see the design-time data appear in the designer.
8) Run and ensure the runtime data appears.
The code displays the form as shown at the top of this post. As you edit the data on the form, note that there is no validation in place. You can type "aaa" into the age. You can delete the first or last name. And you can put in "aaa" into the email address.
See the other posts in this series for information on adding the validation.
Enjoy!
One of the biggest challenges of implementing validation in Silverlight is finding the appropriate technique based on your architecture and goals. There are lots of choices and lots of examples, but not all examples work in all scenarios. Plus many examples demonstrate techniques that are no longer necessary or valid in the current version of Silverlight or when using WCF RIA services.
Below are a set of posts on techniques for performing validation with Silverlight 4.0 using MVVM, WCF RIA Services, and custom business objects.
A few things to keep in mind if you are using Silverlight and WCF RIA Services:
- In most cases, the code should not need to throw exceptions for validation errors.
- The latest version of Silverlight/RIA provides automatic validation and a built-in validation error dictionary, so you do not have to write any code to build or populate validation errors.
The last point is an important one because there are videos and posts that go through the pages and pages of code required to manage your own validation and validation error dictionary. While this code is necessary and useful if you are using WCF directly, it is not necessary if you are using WCF RIA Services.
Here are the links:
Click on a link to navigate to the desired post.
Enjoy!
Elisabeth Sladen died last week on April 19, 2011.
If you are a Doctor Who fan, you know Elisabeth as Sarah Jane Smith, companion to doctor's three and four, a recurring character with the Tenth Doctor (David Tennant), and star of the Sarah Jane Adventures series.
I remember watching her with the Fourth Doctor (Tom Baker) when I was in college. It was such a treat to see her (and K-9) in the revival series with the Tenth Doctor in 2006.
I got my daughter so hooked on Doctor Who, that she watched many of the old episodes and found the Sarah Jane Adventures series online. When the Sarah Jane Adventures came to the SciFi channel, we TiVo'ed it.
Only the first series was broadcast in the US, but I understand that the second series is available on DVD. (To my family: Mother's Day is coming up … hint hint.)
Goodbye Sarah Jane …
In this prior post, I provided information on registering for the Visual Studio Live! conference on April 18-22 in Las Vegas and on the talks I am presenting at that conference. If you would like a "sneak peak" at the source code for my two talks, you can get it all from my company's Web site.
Enjoy!
I am heading to London, Paris, Bruges, and Amsterdam later this week. Anyone have any suggestions for "must see" attractions or "must eat" restaurants?
My oldest daughter has been doing her college semester abroad in London. She has the full month of April off for her spring break, so I'm visiting for a week. Later in April my youngest daughter is going out to visit her for a week.
It will be great to take some time off!
The tick marks on the charts may not look like much, but they can be helpful to clarifying the meaning of your charts.
By default, the tick marks are small little black lines on each axis that identify the axis "ticks". See the following chart. (I put a red circle around one of them since they are a little hard to see.)

This prior post sets the ground work for displaying a chart. This post covers how to format the tick marks on the axes.
NOTE: This post is part of a series that starts with this prior post. The example in this post uses the application that is built as part of that series.
If you have a chart on your page, you already have the necessary namespace:
xmlns:toolkit=
"http://schemas.microsoft.com/winfx/2006/xaml/presentation/toolkit"
To style the axis tick marks, add a CategoryAxis.MajorTickMarkStyle element under the CategoryAxis element within the Chart.Axes element. The XAML is shown below.
<toolkit:Chart.Axes>
<toolkit:CategoryAxis Orientation="X"
Location="Bottom"
Foreground="White">
<toolkit:CategoryAxis.AxisLabelStyle>
<Style TargetType="toolkit:AxisLabel">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate
TargetType="toolkit:AxisLabel">
<TextBlock
Text="{TemplateBinding FormattedContent}"
TextAlignment="Right"
TextWrapping="Wrap"
Width="50"
Margin="-40,-5,0,26"
RenderTransformOrigin="1,.5">
<TextBlock.RenderTransform>
<RotateTransform Angle="300" />
</TextBlock.RenderTransform>
</TextBlock>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</toolkit:CategoryAxis.AxisLabelStyle>
<toolkit:CategoryAxis.MajorTickMarkStyle>
<Style TargetType="Line">
<Setter Property="Stroke"
Value="White" />
<Setter Property="StrokeThickness"
Value="2" />
<Setter Property="Y1"
Value="0" />
<Setter Property="Y2"
Value="10" />
<Setter Property="RenderTransform">
<Setter.Value>
<RotateTransform Angle="15" />
</Setter.Value>
</Setter>
</Style>
</toolkit:CategoryAxis.MajorTickMarkStyle>
</toolkit:CategoryAxis>
</toolkit:Chart.Axes>
This code sets the color using the Stroke property and the thickness using the StrokeThickness property. It sets the line start and end using the Y1 and Y2 properties. It then uses RenderTransform to angle the tick mark so it matches nicely with the angled text.
The result is shown below.

Use this technique any time you want to control the layout and style of the chart tick marks.
Enjoy!
When displaying a chart, you may want to format the x and y axes. This post covers how to set the axis font color and wrap and angle the text.

This prior post sets the ground work for displaying a chart. This post covers how to format the axis. This example formats the x-axis, but you can use the same technique to format either axis.
NOTE: This post is part of a series that starts with this prior post. The example in this post uses the application that is built as part of that series.
If you have a chart on your page, you already have the necessary namespace:
xmlns:toolkit=
"http://schemas.microsoft.com/winfx/2006/xaml/presentation/toolkit"
To style the axis, use the CategoryAxis element within the Chart.Axes element. The XAML is shown below.
<toolkit:Chart.Axes>
<toolkit:CategoryAxis Orientation="X"
Location="Bottom"
Foreground="White">
<toolkit:CategoryAxis.AxisLabelStyle>
<Style TargetType="toolkit:AxisLabel">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate
TargetType="toolkit:AxisLabel">
<TextBlock
Text="{TemplateBinding FormattedContent}"
TextAlignment="Right"
TextWrapping="Wrap"
Width="50"
Margin="-40,-5,0,26"
RenderTransformOrigin="1,.5">
<TextBlock.RenderTransform>
<RotateTransform Angle="300" />
</TextBlock.RenderTransform>
</TextBlock>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</toolkit:CategoryAxis.AxisLabelStyle>
</toolkit:CategoryAxis>
</toolkit:Chart.Axes>
The CategoryAxis element defines the orientation. In this example, the formatting is for the "X" axis. Add a second CategoryAxis element under the Chart.Axes element to format the "Y" axis as well.
The Location property allows you to put the X-axis at the bottom or at the top of the chart. The Foreground property defines the color of the axis text.
The CategoryAxis.AxisLabelStyle allows you to set the template for the axis content. In this example, the style contains a TextBlock, which allows for wrapping and aligning the text.
The Width and Margin adjust the location of the text under the columns. The RenderTransform code angles the text. This is a useful technique if you have text that is long or columns that are close together.
Use this technique any time you want to format or style the chart axes.
Enjoy!
Just in time for the Academy Awards, this post sounds more like a movie title (similar to Death Wish III) than a post asking for new features. But here it is, my "wish list" for features in Silverlight Version "Next".
1) Setting the default file name and location in the print dialog.
a) This item requires that we have access to a system constant (similar to Environment.SpecialFolder). If necessarily, this could be limited to only the MyDocument folder.
2) Ability to select landscape or portrait printing.
3) Improved printing support for styling XAML elements.
a) My thought is to have some type of IsForPrinting flag on most UI elements. If this flag is set to true, the element does not appear except when printed. If this flag is set to false, the element does not appear when printing. If not set, it appears for both display and printing. This would allow developers to define one XAML page layout that would work for both display and printing.
b) A nicety here would also allow for setting the Visual Studio designer so you can see the "display view" or the "print view" so you can WYSIWYG both the display and print view of each page.
4) Expanded built in commanding support so that the InvokeCommandAction is not required.
a) See this reference for more information.
5) Fix to the themes to prevent the chart legend from going missing.
a) See this reference for more information.
6) Keep the expand/collapse of regions in the .xaml files.
a) This would be especially useful in the theme and style files. I spent a while and closed every style element in my theme and style files so I could easily scroll through to find the one style that I needed to edit. To my chagrin, the next time I opened the file the nodes were all opened.
7) Provide some type of refresh button or gesture to refresh the designer.
a) Frequently, changes to the theme or style file were not immediately reflected in the designer. So you either have to make an error in the xaml so it will allow you to fix the error and regenerate the designer UI, or you have to wait for a compile to cause the designer UI to update.
Any other suggestions?
Enjoy!
When displaying a column chart, you may want to display the column value above the column in the chart. Something like this:

This prior post sets the ground work for displaying a chart. This post covers how to modify the chart to display text above each column.
Like most other changes to the chart columns, the key is the DataPointStyle. This time, however, you need to change the Template property.
<toolkit:ColumnSeries DependentValuePath="Project1Score"
IndependentValuePath="StudentName"
ItemsSource="{Binding StudentList}"
Title="{Binding TitleList[0]}">
<toolkit:ColumnSeries.DataPointStyle>
<Style TargetType="toolkit:ColumnDataPoint">
<Setter Property="Background">
<Setter.Value>
<RadialGradientBrush GradientOrigin="-0.1,-0.1"
Center="0.075,0.015"
RadiusX="1.05"
RadiusY="0.9">
<GradientStop Color="#FFFDE79C" />
<GradientStop Color="#FFF6BC0C"
Offset="1" />
</RadialGradientBrush>
</Setter.Value>
</Setter>
<Setter Property="DependentValueStringFormat"
Value="{}{0:N0}%" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate
TargetType="toolkit:ColumnDataPoint">
<Grid Background=
"{TemplateBinding Background}">
<TextBlock Text=
"{TemplateBinding FormattedDependentValue}"
FontWeight="Bold"
Margin="0,-15,0,0"
HorizontalAlignment="Stretch"
TextAlignment="Center" />
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</toolkit:ColumnSeries.DataPointStyle>
</toolkit:ColumnSeries>
The most important change is the Margin on the TextBlock. Setting the top margin to a value of –15 will display the text above the column in the chart.
Enjoy!
By default, Silverlight charts display a tooltip when the user hovers over the chart but it is not very fancy. Here is an example:

So it says 97. Is that a count? Number of points? Percent?
This prior post sets the ground work for displaying a chart. This post covers how to modify the tooltip to display more meaningful information.
The key to modifying the tooltip is to set the DataPointStyle. Setting the DependentValueStringFormat property allows you to format the tooltip as desired.
<toolkit:ColumnSeries.DataPointStyle>
<Style TargetType="toolkit:ColumnDataPoint">
<Setter Property="DependentValueStringFormat"
Value="{}{0:N0}%" />
</Style>
</toolkit:ColumnSeries.DataPointStyle>
Some of the more common formatting strings:
- {}{0:C}
- {}{0:N1}%
- Numeric value, formatted to 1 decimal place and with a % sign
- {}{0:p2}
- Percent value, formatted to 2 decimal places
- {}{0:MM/yy}
- {}{0:MM/dd}
- {}{0:MMM}
- {}Some other text
The problem with setting the DataProintStyle, however, is that you lose all of the automatic color selection for your chart. Your chart will turn orange as shown below.

So you then have to manually set your colors. Setting the colors for the chart is demonstrated in this prior post.
Combining the color and tooltip formatting is as follows:
<toolkit:ColumnSeries.DataPointStyle>
<Style TargetType="toolkit:ColumnDataPoint">
<Setter Property="Background">
<Setter.Value>
<RadialGradientBrush GradientOrigin="-0.1,-0.1"
Center="0.075,0.015"
RadiusX="1.05"
RadiusY="0.9">
<GradientStop Color="#FFFDE79C" />
<GradientStop Color="#FFF6BC0C"
Offset="1" />
</RadialGradientBrush>
</Setter.Value>
</Setter>
<Setter Property="DependentValueStringFormat"
Value="{}{0:N0}%" />
</Style>
</toolkit:ColumnSeries.DataPointStyle>
The final result is shown below.

Use this technique any time you want to format your tooltips in a chart.
Enjoy!
When working with charts, by default the built-in styling sets the chart colors. But there may be times that you want to control the colors. This post covers a technique for manually setting the chart colors.
This prior post sets the ground work for displaying a chart. This current post adds color definition to the chart from that prior post.
The key to setting the color for a bar in the chart is to set the DataPointStyle. Setting the background color of the data point sets the bar color. You can use any brush, including a RadialGradientBrush as shown in the example below.
<toolkit:Chart Name="chart1"
Title="Scores"
VerticalAlignment="Stretch"
HorizontalAlignment="Stretch">
<toolkit:ColumnSeries DependentValuePath="Project1Score"
IndependentValuePath="StudentName"
ItemsSource="{Binding StudentList}"
Title="{Binding TitleList[0]}">
<toolkit:ColumnSeries.DataPointStyle>
<Style TargetType="toolkit:ColumnDataPoint">
<Setter Property="Background">
<Setter.Value>
<RadialGradientBrush GradientOrigin="-0.1,-0.1"
Center="0.075,0.015"
RadiusX="1.05"
RadiusY="0.9">
<GradientStop Color="#FFFDE79C" />
<GradientStop Color="#FFF6BC0C"
Offset="1" />
</RadialGradientBrush>
</Setter.Value>
</Setter>
</Style>
</toolkit:ColumnSeries.DataPointStyle>
</toolkit:ColumnSeries>
<toolkit:ColumnSeries DependentValuePath="Project2Score"
IndependentValuePath="StudentName"
ItemsSource="{Binding StudentList}"
Title="{Binding TitleList[1]}">
<toolkit:ColumnSeries.DataPointStyle>
<Style TargetType="toolkit:ColumnDataPoint">
<Setter Property="Background">
<Setter.Value>
<RadialGradientBrush GradientOrigin="-0.1,-0.1"
Center="0.075,0.015"
RadiusX="1.05"
RadiusY="0.9">
<GradientStop Color="#FF9DC2B3" />
<GradientStop Color="#FF1D7554"
Offset="1" />
</RadialGradientBrush>
</Setter.Value>
</Setter>
</Style>
</toolkit:ColumnSeries.DataPointStyle>
</toolkit:ColumnSeries>
<toolkit:ColumnSeries DependentValuePath="Project3Score"
IndependentValuePath="StudentName"
ItemsSource="{Binding StudentList}"
Title="{Binding TitleList[2]}">
<toolkit:ColumnSeries.DataPointStyle>
<Style TargetType="toolkit:ColumnDataPoint">
<Setter Property="Background">
<Setter.Value>
<RadialGradientBrush GradientOrigin="-0.1,-0.1"
Center="0.075,0.015"
RadiusX="1.05"
RadiusY="0.9">
<GradientStop Color="#FFFBB7B5" />
<GradientStop Color="#FF702828"
Offset="1" />
</RadialGradientBrush>
</Setter.Value>
</Setter>
</Style>
</toolkit:ColumnSeries.DataPointStyle>
</toolkit:ColumnSeries>
</toolkit:Chart>
The result is shown below.

Use this technique any time you need to set the colors of the columns in the chart.
Enjoy!
Many users want to print information from your line of business (LOB) application. This post covers the simple case where the user wants to print a copy of what they see on the screen. But instead of putting the print code in the code behind file, it follows a Model-View-View/Model (MVVM) approach.
NOTE: This post is part of a series that starts with this prior post. The example in this post uses the application that is built as part of that series.
NOTE: If you are new to MVVM, this prior post provides an introduction.
Silverlight 4 introduced two features that are the basis of this post: printing support and commanding.
Using the built-in commanding feature to support printing requires the following steps:
1) Create a command class that implements the ICommand interface.
2) Create a property of type ICommand in the View/Model class for a PrintCommand.
3) Build a button to launch the printing and bind the Command property of the button to the property created in 2 above.
Creating a Command Class
The code for this class was provided in this prior post and is not repeated here.
Creating a Property in the View/Model
Add three things to the View/Model for each command:
1) Command property.
2) Code to set the command property.
3) Method defined for the command property delegate.
The code is shown below with the statements for 1, 2, and 3 above shown in red.
In C#:
using System;
using System.Collections.ObjectModel;
using System.ServiceModel.DomainServices.Client;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Printing;
using InStepSM.Library;
using InStepSM.SL.Web;
namespace InStepSM.SL.ViewModels
{
public class StudentsViewModel : ViewModelBase
{
private ICommand _PrintCommand;
public ICommand PrintCommand
{
get
{
return _PrintCommand;
}
}
private ICommand _SaveCommand;
public ICommand SaveCommand
{
get
{
return _SaveCommand;
}
}
private StudentContext StudentContextInstance;
private ObservableCollection<Student> _StudentsList;
public ObservableCollection<Student> StudentsList
{
get
{
return _StudentsList;
}
set
{
if (_StudentsList != value)
{
_StudentsList = value;
OnPropertyChanged("StudentsList");
}
}
}
public StudentsViewModel()
{
LoadData();
DefineCommands();
}
private void DefineCommands()
{
_SaveCommand = new DelegateCommand<Student>
(OnSaveCommand);
_PrintCommand = new DelegateCommand<Panel>
(OnPrintCommand);
}
/// <summary>
/// Loads the data for the application.
/// </summary>
private void LoadData()
{
if (IsInDesignModeStatic)
{
LoadDesignData();
}
else
{
// Load the student data asynchronously
StudentContextInstance = new StudentContext();
var loadop =
StudentContextInstance.Load(StudentContextInstance.
GetStudentsQuery(),
OnStudentsLoaded, null);
}
}
/// <summary>
/// Loads temporary data for use in the designer.
/// </summary>
/// <remarks></remarks>
private void LoadDesignData()
{
//Design mode data
ObservableCollection<Student> temp =
new ObservableCollection<Student>();
temp.Add(new Student
{
LastName = "Baggins",
FirstName = "Bilbo",
Age = 111,
Email = "testemail@live.com",
RegistrationDate = DateTime.Now
});
temp.Add(new Student
{
LastName = "Baggins",
FirstName = "Frodo",
Age = 32,
Email = "testemail@yahoo.com",
RegistrationDate = DateTime.Now
});
StudentsList = temp;
}
private void OnPrintCommand(Panel p)
{
PrintDocument pd = new PrintDocument();
pd.PrintPage += (s, e) =>
{
p.Width = e.PrintableArea.Width;
p.Height = e.PrintableArea.Height;
e.PageVisual = p;
e.HasMorePages = false;
};
pd.Print("Student List");
}
private void OnStudentsLoaded(LoadOperation lo)
{
StudentsList =
new ObservableCollection<Student>(StudentContextInstance.Students);
}
private void OnSaveCommand(Student s)
{
StudentContextInstance.SubmitChanges();
}
}
}
In VB:
Imports System.Collections.ObjectModel
Imports System.ServiceModel.DomainServices.Client
Imports InStepSM.SL.Web
Imports System.Windows.Printing
Imports System.Windows.Controls
Namespace ViewModels
Public Class StudentsViewModel
Inherits ViewModelBase
Private _PrintCommand As ICommand
''' <summary>
''' Processes the Save command
''' </summary>
Public ReadOnly Property PrintCommand() As ICommand
Get
Return _PrintCommand
End Get
End Property
Private _StudentsList As ObservableCollection(Of Student)
Public Property StudentsList() As _
ObservableCollection(Of Student)
Get
Return _StudentsList
End Get
Set(ByVal value As ObservableCollection(Of Student))
If _StudentsList IsNot value Then
_StudentsList = value
OnPropertyChanged("StudentsList")
End If
End Set
End Property
Private StudentContextInstance As StudentContext
Private _SaveCommand As ICommand
''' <summary>
''' Processes the Save command
''' </summary>
Public ReadOnly Property SaveCommand() As ICommand
Get
Return _SaveCommand
End Get
End Property
Public Sub New()
LoadData()
DefineCommands()
End Sub
Private Sub DefineCommands()
_SaveCommand = New DelegateCommand(Of Student)(
AddressOf OnSaveCommand)
_PrintCommand = New DelegateCommand(Of Panel)(
AddressOf OnPrintCommand)
End Sub
''' <summary>
''' Loads the data for the application.
''' </summary>
Private Sub LoadData()
If IsInDesignModeStatic Then
LoadDesignData()
Else
' Load the student data asynchronously
StudentContextInstance = New StudentContext
Dim loadop =
StudentContextInstance.Load(StudentContextInstance.
GetStudentsQuery(),
AddressOf OnStudentsLoaded, Nothing)
End If
End Sub
''' <summary>
''' Loads temporary data for use in the designer.
''' </summary>
''' <remarks></remarks>
Private Sub LoadDesignData()
' Design mode data
Dim temp As New ObservableCollection(Of Student)
temp.Add(New Student With {.LastName = "Baggins",
.FirstName = "Bilbo",
.Age = 111,
.Email = "testemail@live.com",
.RegistrationDate = Now()})
temp.Add(New Student With {.LastName = "Baggins",
.FirstName = "Frodo",
.Age = 32,
.Email = "testemail@yahoo.com",
.RegistrationDate = Now()})
StudentsList = temp
End Sub
Private Sub OnPrintCommand(ByVal p As Panel)
Dim pd As PrintDocument = New PrintDocument()
AddHandler pd.PrintPage,
Sub(s, e)
p.Width = e.PrintableArea.Width
p.Height = e.PrintableArea.Height
e.PageVisual = p
e.HasMorePages = False
End Sub
pd.Print("Student List")
End Sub
Private Sub OnStudentsLoaded(ByVal lo As LoadOperation)
StudentsList =
New ObservableCollection(Of Student)(StudentContextInstance.Students)
End Sub
Private Sub OnSaveCommand(ByVal s As Student)
StudentContextInstance.SubmitChanges()
End Sub
End Class
End Namespace
The PrintCommand is the property that implements ICommand. The UI can be bound to this property.
The DefineCommands method assigns the PrintCommand to a new instance of the DelegateCommand class. Notice that it uses a Panel as the parameter. That allows passing any control that inherits from Panel to the PrintCommand. Controls that inherit from Panel include Grid and StackPanel.
The OnPrintCommand is the method to be executed when the command occurs. This method creates an instance of PrintDocument, which is the primary class for handling printing in Silverlight. It then defines a delegate for the PrintPage event. Finally, it calls the Print method of the PrintDocument to start the printing process.
The PrintPage event is generated for each page to be printed. When the PrintPage event occurs, the delegate code sets the size of the passed in control to fit the printable area of the page. It then assigns the PageVisual to the control. All controls in the tree of the control assigned to the PageVisual are printed. Setting the HasMorePages to false indicates that there is only one page to print.
Binding to the Command
This last step is to define a control in the xaml that launchs the printing. In this example, a Print button is used. The xaml for the button is as follows:
<Button Command="{Binding PrintCommand}"
CommandParameter="{Binding ElementName=LayoutRoot}"
Content="Print"
HorizontalAlignment="Right"
Name="PrintButton"
Margin="10"
Width="60" />
The Command property of the Button is bound to the PrintCommand property from the View/Model. The CommandParameter property of the Button is bound to the LayoutRoot element of the page, which is the main grid on the page. The resulting printed output is shown below:

But maybe you don't want the entire page with the title and buttons. If so, just assign a different control to the CommandParameter.
For example, you can put a StackPanel around just the DataGrid and pass the name of the StackPanel in as the CommandParameter. The resulting printed output then only includes the DataGrid.

Use this technique any time you need to print the content or some portion of the content of your Silverlight page to the printer.
Enjoy!
More Posts
Next page »