Rants Tagged with “Silverlight”

If you would like to hear me blather on at MIX about how to create Silverlight applications, feel free to go visit the MIX site and vote for my sessions. I submitted seven talks so feel free to pick your favorites. You'll have the opportunity to vote for five of your favorite sessions. Remember, even if you don't think you can go, these are the sessions that will be recorded and available after MIX...so everyone gets a chance to vote!
You can see my sessions by visiting:
http://visitmix.com/opencallvote/?query=Shawn%20Wildermuth

Welcome the part 4 of my three-part series on architecting with RIA Services. In the last part of the series, I thought I was done with the example and some of my readers challenged me to help them understand how to handle Add/Delete scenarios. Since I was at it, I figured I should show paging and IsDirty scenarios as well, I decided to make a part four.
Remember this example is based on my current thoughts, its not dogma. I will change my mind at times and learn from the community (as has even happened during this series). Hopefully this example can help you think about how the patterns match your current business problems. No tithe, no sermon, no damnation....I promise ;)
Supporting IsDirty
To be able to support some functionality (like using it in some Commands' CanExecute call), I wanted to test the model for whether it had saveable entities. My first try was to ask the RIA Services' context HasChanges property:
public bool HasChanges
{
get { return Context.HasChanges; }
}
This works *but* the problem is that this property tests to see if the context has any changes. Why does this matter? I realized that as I made additional queries that the context was holding on to every object I retrieved. This means that if I changed an object and switched the Genre, the object was still in memory unchanged. More importantly, the size of the cache in the context was growing every time. I didn't want this so I changed the way I was handling the returned values.
The context has a collection of EntitySet objects. Each EntitySet is for a particular data type. I wanted to change the behavior to only have a single set of games at any particular time. This way my call to HasChanges was only testing the current set of games, not every game I've ever loaded. To do this, I made one small change:
void PerformGameQuery()
{
// Clear the games so we don't consume a lot of memory
Context.Games.Clear();
...
}
This allows us to remove games we no longer care about.
Server Paging
We should start with the paging story since that affects the design of the add/delete functionality. In RIA Services paging is pretty simple. Since the query to the server can contain some very simple LINQ expressions, we can use the Skip and Take expressions to shape the result (Where and OrderBy are also supported). For example if we want to get the second page where the page size is ten records:
// Generate the query with paging
var qry = Context.GetGamesByGenreQuery("Shooters")
.Skip(10)
.Take(10);
Context.Load<T>(qry, OnGamesLoadedComplete);
The Skip expression tells RIA Services to look at the result (on the server) and skip those records; The Take expression tells RIA Services to limit the number of results returned (like a TOP clause in SQL). Using them together allows us to page. But I like the hide the paging in the Model. Sure the ViewModels will need to know about the paging, but they shouldn't control the size or method of paging. To achieve this, I've added a couple of properties to my model:
public class GamesModel : IGamesModel
{
private int _currentGamesPage = 0;
private readonly int GAMESPAGESIZE = 15;
private string _lastGenre;
...
Using these parts of the model, I can handle the size and current page. One problem with this design though is that its emparting state into the Model. But since our Model already has the data context which holds onto references to returned elements, I think this is an acceptable solution.
The paging then becomes pretty simple, when GetGamesByGenre is called, we get the first page (and reset the paging mechanism):
public void GetGamesByGenreAsync(string genre)
{
_currentGamesPage = 0;
_lastGenre = genre;
// Generate the query with paging
var qry = Context.GetGamesByGenreQuery(_lastGenre)
.Skip(_currentGamesPage * GAMESPAGESIZE)
.Take(GAMESPAGESIZE);
...
When the initial call to GetGamesByGenreAsync happens, we reset the paging and store the last genre (so we can use it when we get subsequent pages). In the query, we calculate the page and execute that query. When NextPage/PrevPage are called, we use this same data to calculate the subsequent pages:
public void GetPrevPageGamesAsync()
{
if (_currentGamesPage > 0)
{
_currentGamesPage--;
// Generate the query with paging
var qry = Context.GetGamesByGenreQuery(_lastGenre)
.Skip(_currentGamesPage * GAMESPAGESIZE)
.Take(GAMESPAGESIZE);
}
}
public void GetNextPageGamesAsync()
{
_currentGamesPage++;
// Generate the query with paging
var qry = Context.GetGamesByGenreQuery(_lastGenre)
.Skip(_currentGamesPage * GAMESPAGESIZE)
.Take(GAMESPAGESIZE);
}
Once the model supports this, the ViewModel can use it via a Command:
RelayCommand _prevPageCommand = null;
public RelayCommand PreviousPage
{
get
{
if (_prevPageCommand == null)
{
_prevPageCommand = new RelayCommand(
() => _model.GetPrevPageGamesAsync(),
() => Games != null && Games.Count() > 0);
}
return _prevPageCommand;
}
}
private RelayCommand _nextPageCommand = null;
public RelayCommand NextPage
{
get
{
if (_nextPageCommand == null)
{
_nextPageCommand = new RelayCommand(
() => _model.GetNextPageGamesAsync(),
() => Games != null && Games.Count() > 0);
}
return _nextPageCommand;
}
}
Then these commands can be data bound to controls (in my case buttons). Typically I am immediately asked about how to know when you've reached the end of paging. This is a little wierd because you could handle it by determining if the number returned is less than a full page but because it *can* be the last page and return the full number of the page you can't rely on it. The other solution is to determine it on the server, but in most cases (as the server results can change in a Transactional System), I just try and get the next page and if the number of results equals zero, I move the page counter back one and reload the results. Its not as efficent but it is only non-efficient in an edge case (returning exactly the page size as the last page. In the Model I handle this like so:
else if (r.Entities.Count() == 0 && _currentGamesPage > 0)
{
// If the page returned no results we
// reached the end of a page edge
// (important since we're not getting
// full result counts from the server)
GetPrevPageGamesAsync();
}
Dealing with Add/Delete
While I differ from the RIA teams view, I like to isolate the RIA Service layer inside the Model completely. That means that the model can be responsible for the actual adding removing of the items. But this represents a problem. In our earlier parts to this series, I returned the results of the loading query directly to the ViewModel to use as it's data. The datatype we returned was an IEnumerable<T> object. Ordinarily this works but since we're supporting adding and removing, the IEnumerable<T> object doesn't support that. So I dug a little deeper to see if the actual returning object supported ICollection or ICollection<T>. Nope. In fact, the underlying object is a ReadOnlyCollection<T>. Yup, read-only. So our original assumption to return the results wasn't helpful Instead, I changed this to return the EntitySet directly from the RIA Services' Context object:
// Returning the raw Games collection since the
// entity results are a ReadOnly collection
evt(this, new EntityResultsArgs<Game>(Context.Games));
Since the underlying type that the EntityResultsHandler is expecting is still IEnumerable<T> we could do one of two things, either change the event to allow a richer object (e.g. ICollection) or let the model to be reponsible for Adding/Removing of objects. I chose the latter:
public class GamesModel : IGamesModel
{
...
public Game AddNewGame()
{
var g = new Game()
{
GameID = 0,
Name = "*TODO*"
};
Context.Games.Add(g);
return g;
}
public void DeleteGame(Game g)
{
Context.Games.Remove(g);
}
...
}
I don't prefer this solution. I would prefer to have a monitored ObservableCollection<T> that is watched for add/delete operations but since RIA Services doesn't work that way, this work around is acceptable.
To allow for any of the views to issue these commands, I chose to use another application message like we dicussed in prior parts of this series. In this case, while the model is doing the real work of adding and removing, there is still some work to be done once the game is added or deleted. For example here is the event for adding an item:
AppMessages.AddNewGameMessage.Register(this,
ignore =>
{
CurrentGame = _model.AddNewGame();
});
In the MVVM Light implementation of their Messenger, they don't allow for no actual data being sent with the message, so I just use an object and in the lambda I named it ignore so you could tell that it was a dummy piece of data. Inside the message handler, you can see I am calling the model to add the new game, but then setting the current game to be the new game (so that it can be immediately edited). All of this happens in the GamesListViewModel so by setting the new game as the CurrentGame we get both that the ListBox in the view is selected as well as a message is being sent out (that the GameEditViewModel listens for) that a new CurrentGame has been selected which allows it to be edited. Again, the model is responsible for the record-keeping, but the view model continues to work as expected to communicate with the actual view.
The delete message is the same:
AppMessages.DeleteCurrentGameMessage.Register(this,
ignore =>
{
_model.DeleteGame(CurrentGame);
CurrentGame = null;
});
In this case we tell the model to delete the game and mark the current game as a null reference which prevents the editing in the edit view as well as deselects the item from the ListBox in the List view. This pattern should allow you to continue separating your concerns between the different layers.
You can get the final version of the example here:
http://wildermuth.com/downloads/riaxboxgames.zip

As many of you who've been following know, I use a simple database of XBox game data as my example database. I usually remember to include it on the server project but in some examples its been forgotten. In other cases I've shipped with a 2008 version of the database instead of the 2005 version. To address this, I've uploaded .zip'd versions of both the 2005 and 2008 databases for anyone to use for any reason. This includes my RIA Services sample (which is using a SQL Server 2008 version) or my MVVM MSDN article sample which also uses a 2008 version. They include a MDF and a LDF. If you have trouble attaching them to an existing database, try deleting the LDF file. Go grab there here:
Any questions/problems, post a comment!

While in Sweden for OreDev, Microsoft pulled me aside to do a quick interview about Silverlight, Data and the reported death of WPF. Daniel Mellgaard Frost does a great job of asking me the tough questions about Silverlight. Note that this interview happened before Silverlight 4 was announced so some of my answers would be different today.
As many of you don't know, I was previously known as "The ADO Guy" so of course my first jump into the new Silverlight 4 bits was to play with the new Data Binding changes. The improvements aren't dramatic but they do fill several key holes that existed in the earlier versions. Let's take these changes one at a time.
DependencyObject Binding
Prior to Silverlight 4, in order to support data binding, the object had to derive from the FrameworkElement class which left out some key objects including Transformations. Now data binding works on any object that derives from DependencyObject (which is most of the Silverlight 4 framework). You can see this in the example below. (Note, you can also see the CompositeTransform which lets you set transformations of all four types in a single transform):
<Grid x:Name="LayoutRoot"
Background="White">
<StackPanel Width="400"
Height="300">
<StackPanel.RenderTransform>
<CompositeTransform
ScaleX="{Binding Value,ElementName=stretcher}"
ScaleY="{Binding Value,ElementName=stretcher}" />
</StackPanel.RenderTransform>
<ListBox ItemsSource="{Binding}"
Width="400"
Height="300">
</ListBox>
</StackPanel>
<Slider Minimum=".5"
Maximum="4"
x:Name="stretcher"
Value="1" VerticalAlignment="Top" />
</Grid>
By adding the ability to use data bindings on DependencyObject derived objects, Silverlight 4 opens up using UI interactions through XAML.
String Formatting
Additionally, Silverlight 4 adds the ability to do string formatting directly in the data binding. Previously you would have to use a Converter to format data during binding. This greatly simplifies straightforward formatting of data into strings like dates and money values. It even uses the format to perform parsing for two-way data binding. To use it, simply use the markup extension "StringFormat" and the format (short or long form) as shown below:
<TextBox Text="{Binding ReleaseDate, StringFormat='MMM dd, yyyy',
Mode=TwoWay}" />
<TextBlock Text="{Binding Price, StringFormat='c'}" />
Null and Fallback Values
Data binding has also added the ability to specify what to show in certain cases. These cases include when the value is NULL and when the value fails to load. There are two markup extensions that support this. First the TargetNull markup extension lets you specify what to show when the bound value is null. Secondly, the FallbackValue is used in the same way but is shown when the value cannot be loaded through data binding (normally when the DataContext is null or fails to find the property on the bound object). Here is an example of how that works:
<TextBlock Text="{Binding Developer, TargetNullValue='(None)'}" />
<TextBlock Text="{Binding Publisher, FallbackValue='(Nope)'}" />
CollectionViewSource Changes
For all of you who are doing grouping (using the DataGrid or similiar controls), good news. The CollectionViewSource now supports data binding to the GroupDescriptions so you can more easily describe your grouping in XAML.
Error Propogation
The Silverlight 3 validation stack was a good start, but still left a bit to be desired. Following the request from the community, controls will now use the IDataErrorInfo interface to get error information on your bound objects if it is available. To make this facility even better, they've introduced INotifyDataErrorInfo interface so that live bindings can efficiently know about changes to the IDataErrorInfo interface's data.
Overall I am happy with the set of data binding functionality. Enjoy playing with Silverlight 4 and let me know what you think of these changes!
As noted in Scott Guthrie's keynote early, Silverlight 4 is now in beta. But what does that mean to you? Silverlight 4 Beta does not have a go-live license, so if you're building something to be released soon, I would stick with Silverlight 3. In contrast if you're working on a longer term project, especially a line-of business application, you'd be crazy to not look at Silverlight 4. Here are some of the major changes in this release:
General
- Printing Support
- Implicit Styling
- WebCam/Microphone Support
- RichTextArea Control
- Right-Mouse Button Events
- Drag-n-Drop/Clipboard Access
- UDP/Multicast Support in Networking
Out of the Browser Improvements
- Elevated Trust
- WebBrowser Control
- Controlling the Window
- Notification Windows (e.g. Outlook popup's)
- COM Integration
Data Binding Improvements
- Binding to DependencyObjects (used to be FrameworkElement)
- StringFormat Markup Extension
- TargetNullValue Markup Extension
- FallbackValue Markup Extension
- Support for IDataErrorInfo and new INotifyDataErrorInfo for reporting validation errors.
- Binding to String Indexers
- GroupDescription support on CollectionViewSource for simplified grouping.
That's a splendid list of improvements. I will be writing blog entries about some of my favorites this week. So keep an eye out for some examples!

Last week I had the pleasure of presenting again at the SDN Conference. I had a great time at the conference. I ended up presenting (or co-presenting) six talks at the conference. The Silverlight talks were some of my favorites:
In addition, I gave a breakout session at the Windows 7 launch (where they gave away 100 copies of Windows 7). My talk at the launch was:
- Adding Windows 7 Features to Your .NET Applications
I was able to show off how to create TaskDialogs, Taskbar features like progress, thumbnails and jumplists. I had a lot of fun doing that talk (et lekker!).
A couple of days before the talk, I noticed that Ted Neward and I had a similar talk on MGrammar so we decided to co-host both sessions. Since Oslo is early, there were a lot of skeptics in the rooms; not all did we convert but it did create some very interesting discussion of what is a Domain Specific Language and whether Oslo is the key to DSLs in the Microsoft space. The talks I did on Oslo included:
Of course conferences are not just about doing talks. They are also about visiting with *my* favorite speakers. The usual bunch were there:
Carl Franklin

Steve Forte and Richard Campbell

Beth Massi

Ted likes his soup:

Paco Likes Soup too (aka Hadi Hariri)

Its been a fun time, and almost 1/2 over.

While in Bulgaria, I was asked to sit down with Tibu Tiberiu “Tibi” Covaci for five minutes for a short list of questions. He's released the short podcast and go take a look here if you're interested in hearing what I have to say about the future of technology.
http://www.cloudcasts.net/ViewWebcast.aspx?webcastid=2521462397756387551

Before I left for Europe, I had a chance to sit down with Richard and Carl and espouse my views on views. Specifically we discussed how the separation of UIs (in declarative UI's like XAML and JavaScript templating) may help developers know specifically when they are in or out of the user interface part of their project. Hopefully this will make it easier to keep our code from getting tangled. Watch out for the bad pizza/spagetti code reference...

As I've been on the mend lately, i've been looking deep into how Validation should work in Silverlight. As I am trying to expand some of hte validation scenarios in Silverlight (in my Niagara project), I'd like to see how you are feeling about Validaiton.
Currently (as my previous post mentioned), the current validation stack is pretty tightly coupled to RIA Services (though with some work you can get it working with other data stacks). But the question is really which validation stack does Silverlight really need. Let's discuss the two I've been looking at: DataAnnotations and Enterprise Libraries' Validation Application Block.
DataAnnotations
Let's talk history. Back in .NET 3.5 SP1 (ok, I know many of you are still in .NET 2.0, my apologies), the DataAnnotations assembly was shipped. My assumption that this was to accomodate the newly christened Dynamic Data Web projects. Dynamic Data needed a way to communicate information it couldn't discern (like required fields, string length, etc.) The way that it did this was via a set of attributes in the System.ComponentModel.DataAnnotations. For example:
public class GameInfo
{
[Required]
[StringLength(100)]
public string Name { get; set; }
[Range(0d, 1000d)]
public decimal Price { get; set; }
}
The problem with this approach was that in most cases, the classes were generated via an ORM (LINQ to SQL, Entity Framework, etc.) and adding these attributes on generated code just doesn't work. So someone came up with a workaround (or a hack if you prefer): the Metadata Type.
The idea behind a metadata type was that with partial types, users can add attributes to a class (but not a property) so by adding an attribute to each entity class that said, the metadata (e.g. validation attributes) for this class are stored in this metadata type that is never used except as a payload for the metadata about our entity. For example:
[MetadataType(typeof(Game.GameMetadata))]
public partial class Game
{
internal sealed class GameMetadata
{
// Metadata classes are not meant to be instantiated.
private GameMetadata()
{
}
public string Description;
public string Developer;
public EntityState EntityState;
public int GameID;
public Genre TheGenre;
public string ImageUrl;
[Required]
[StringLength(100)]
public string Name;
[Range(0d, 2000d)]
public Nullable Price;
public string Publisher;
public Rating TheRating;
public Nullable ReleaseDate;
}
}
Early on, using the metadata classes to add these bits of data may have made sense because the sites you were creating were quick and dirty data editing sites. The problem is that this stack was adopted by RIA Services to allow for better validation in the Silverlight space (and eventually other platforms).
The DataAnnotations in RIA Services are a bit fractured as well. There are no less than three versions of the DataAnnotations that can cause confusion. The atttributes lists are different in these three versions:
- .NET 3.5 SP1's System.ComponentModel.DataAnnotations
- RIA Services's System.ComponentModel.DataAnnotations
- Silverlight's System.ComponentModel.DataAnnotations
The three versions can cause some confusion as the attributes that you can use are duplicative (See .NET 3.5 SP1's Description attribute versus RIA Service's as an example).
The current Silverlight validation stack relies on exceptions to be thrown during set property setters (or you can validate the whole objects yourself). While this works, it does seem at odd with the work at hand and having a simple Validation model that returned results would be better IMHO. I understand that RIA Services was trying to fit into an existing Silverlight model but that doesn't mean I have to like it.
This stack may be good enough, especially with the ability to do custom validation with RIA Services but I sense that it may be too shallow for real validation.
Enterprise Library's Validation Application Block
On the other side of the coin is the Patterns and Practice team's Validation Application Block (VAB). This is a set of code that allows you to specify validation using either attributes or configuration files. While the Validation Application Block doesn't support Silverlight directly, I've been investigating it as an alternative design.
The Validation Application Block's design is focused on some of the same principals as the DataAnnotations but they were trying to solve some different problems. Some of the features of that design that may be of use in Silverlight are:
- Multi-level validation (e.g. Validates with And/or clauses: "NULL or StringLength 5-25")
- Configuration doesn't rely on attributes but can use them
- Uses a provider model for specifying the validation so other sources of validation metadata are possible
- Large number of built-in validations
- Support for multiple sets of validation (RuleSets)
- Validation is object-based to allow for cross validation (Either Name or CompanyName but not be null).
- Fail-over validation detection (e.g. look for attributes, if not found look up configuration, etc.)
- Validation returns simple ValidationResults which can be parsed or shown to the user. No Exceptions requried.
For example a typical attribute scenario for validation looks a lot like the RIA Services' approach:
[StringLengthValidator(1, 50,
Ruleset="RuleSetA",
MessageTemplate="First Name must be between 1 and 50 characters")]
public string FirstName
{
get { return firstName; }
set { firstName = value; }
}
[StringLengthValidator(1, 50,
Ruleset = "RuleSetA",
MessageTemplate = "Last Name must be between 1 and 50 characters")]
public string LastName
{
get { return lastName; }
set { lastName = value; }
}
[RelativeDateTimeValidator(-120,
DateTimeUnit.Year, -18, DateTimeUnit.Year,
Ruleset="RuleSetA",
MessageTemplate="Must be 18 years or older.")]
public DateTime DateOfBirth
{
get { return dateOfBirth; }
set { dateOfBirth = value; }
}
[RegexValidator(@"\w+([-+.']\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*",
MessageTemplate="Invalid e-mail address",
Ruleset = "RuleSetA")]
public string Email
{
get { return email; }
set { email = value; }
}
[ObjectValidator("RuleSetA", Ruleset = "RuleSetA")]
public Address Address
{
get { return address; }
set { address = value; }
}
[RangeValidator(0, RangeBoundaryType.Inclusive,
1000000,
RangeBoundaryType.Inclusive,
Ruleset = "RuleSetA",
MessageTemplate="Rewards points cannot exceed 1,000,000")]
public int RewardPoints
{
get { return rewardPoints; }
set { rewardPoints = value; }
}
In addition it supports a configuration-based solution:
<validation>
<type assemblyName="ValidationQuickStart.BusinessEntities,
Version=1.0.0.0,
Culture=neutral, PublicKeyToken=null"
name="ValidationQuickStart.BusinessEntities.Address">
<ruleset name="RuleSetB">
<properties>
<property name="City">
<validator lowerBound="1"
lowerBoundType="Inclusive"
upperBound="30"
upperBoundType="Inclusive"
negated="false"
messageTemplate=""
messageTemplateResourceName=""
messageTemplateResourceType=""
tag=""
type="Microsoft.Practices.EnterpriseLibrary.
Validation.Validators.StringLengthValidator,
Microsoft.Practices.EnterpriseLibrary.Validation"
name="String Length Validator" />
<validator characterSet="1234567890!@#$%^&*()-="
containsCharacter="Any"
negated="true"
messageTemplate="City may not contain numbers"
messageTemplateResourceName=""
messageTemplateResourceType=""
tag=""
type="Microsoft.Practices.EnterpriseLibrary.Validation.
Validators.ContainsCharactersValidator,
Microsoft.Practices.EnterpriseLibrary.Validation"
name="Contains Characters Validator" />
<validator negated="false"
messageTemplate=""
messageTemplateResourceName=""
messageTemplateResourceType=""
tag=""
type="Microsoft.Practices.EnterpriseLibrary.Validation.
Validators.NotNullValidator,
Microsoft.Practices.EnterpriseLibrary.Validation"
name="Not Null Validator" />
</property>
</ruleset>
</type>
</ruleset>
</validation>
This syntax while it works, its pretty terse and unreadable (as configuration tends to be). But it is decoupled which is nice.
While many of these features are laudable, it feels a bit over-engineered and complex. The VAB uses Validators for a number of cases where its just a grouping technique so debugging individual validations can be complex.
"Just Right?"
So here is where I put it to you, my readers:
"What do you need in Silverlight?"
- Is the RIA Stack good enough?
- Do you want validation regardless of what the transport is (ADO.NET Data Services, WCF, REST)?
- Is using RIA Services' CustomValidation with method name good enough for custom scenarios?
- Do you need complex validation (where AND/OR validation is necessary)?
- How important is decoupling your validation metadata from the model?
- Do you detest metadata types or is it just a necessary evil?
Please comment here so we can start a dialogue to help me understand what the development community is thinking about validation.