WPF Reflections

Mar 26 2008   8:49AM GMT

Data validation using IDataErrorInfo



Posted by: Mark Shurmer
WPF, Databinding, XAML

As per a previous post, how do you do data validation in WPF using IDataErrorInfo?

Well what does IDataErrorInfo give you? It defines two properties:

public string Error
{
get;
}

public string this[string columnName]
{
get;
}

When you implement these, you provide error validation for your WPF application.

How does that happen?
Well, it doesn’t automatically of course [no surprises there].

When you specify your binding in xaml, you need to specify either the ValidationRules element or the ValidatesOnDataErrors parameter:

<Binding Source=”{StaticResource tradeList}” Path=”Instrument” UpdateSourceTrigger=”PropertyChanged”>

<Binding.ValidationRules>

<DataErrorValidationRule>

</Binding.ValidationRules>

</Binding>

or

<Binding Source=”{StaticResource tradeList}” Path=”Instrument” ValidatesOnDataErrors=”true” />

Mar 14 2008   4:50PM GMT

Validation



Posted by: Mark Shurmer
WPF, XAML, Validation

There seems to be four ways to go with validation with WPF:

  1. Use IDataErrorInfo
  2. Use custom classes with ValidationRule
  3. Combine 1 and 2
  4. Roll your own

What do I mean by each of these, and why?

  1. Use IDataErrorInfo. You canimplement this interface in your business objects and you get the opportunity to specify validation for each property or for all properties. You do this in (usually) a general purpose method that does validation for all of your properties in your business object. This is good if you need validation for a business object, but not across objects. You can tell wpf to use it (in v3.5) by specifying ValidatesOnDataErrors=”True” in your binding specification.
  2. Inherit a class from ValidationRule, and provide an override for the Validate method. You could do this for either a particular business object, or across a number of objects. You can use it in xaml by specifying it in the binding’s ValidationRules collection.
  3. Do 1 for business object validation, and 2 for any validation that needs to be done across business objects
  4. Do this when you need to extend the validation, e.g. like in the CSLA.Net framework


Mar 14 2008   3:47PM GMT

DevWeek08



Posted by: Mark Shurmer
WPF

I went to DevWeek08 this week, and saw some excellent presentations, and some not so….

I particularly liked the talks by Christian Weyer and Richard Blewett on .Net 3.5

However, there wasn’t a huge amount of WPF stuff. I saw a couple of talks by David Wheeler, just to see how it was panning out in the real world. They were very popular, so I wonder if the organisers might have put on more WPF talks. One of the talks was on multi-threading in WPF, and Dave was a very entertaining talker although the content wasn’t that deep due to time constraints.

Silverlight was overshadowing WPF, as I suspect it will in the general world of IT :-)
The talks on Silverlight by Jeff Prosise were also excellent, and his enthusiasm for the subject matter was clear.
It has made me realise two things that I didn’t know:

1. A beta of Silverlight was released last week (for MIX08 in USA I believe), and actually has some decent stuff in it. And it works :-)
2. It really is cool :-), so I think I might do some posts on the experienc


Mar 10 2008   9:39PM GMT

Re-using data template across controls



Posted by: Mark Shurmer
Databinding, WPF, XAML

How do you use the same data template across different types of control?

Well you can :-)

Normally when you define the data template, you do something like the following:

<DataTemplate DataType=”{x:Type ListViewItem}>
<TextBlock Text=”{Binding Path=ISIN}” />
</DataTemplate>

However, it is a bit of a pain to then copy it for different types, but there is a way:

<DataTemplate DataType=”{x:Type local:Instrument}>
<TextBlock Text=”{Binding Path=ISIN}” />
</DataTemplate>

(where Instrument is a class in your assembly)

This template can now be used with any control type.


Mar 9 2008   6:53AM GMT

Multi value converter in databinding



Posted by: Mark Shurmer
XAML, C, Databinding, WPF

Here’s a nifty little trick that I recently discovered.

When you need to calculate the result of two properties and display it, you can do it via a Converter class.
You may want to do it, like me, if you couldn’t update the business objects, or didn’t want to.

How do you do it?
Your converter class needs to implement IMultiValueConverter instead of IValueConverter.

E.g.:

Converter class

Then you specify a multi binding in your xaml, like:

blog08mar2008-window.JPG


Mar 6 2008   2:45PM GMT

Explicit control of how the source is updated



Posted by: Mark Shurmer
WPF, Databinding, XAML

In a previous post, I described how you can get a binding to update in real time - i.e. as you type.
Sometimes however, you want to control the updating more closely, i.e. in code. For example, you may want to do the update only when a timer has ticked.
There is a little used argument for UpdateSourceTrigger (well in 18 months of using WPF I’ve never seen it used :-)) , namely Explicit that allows you to do that.
Given some xaml like:

<ComboBox Name=”cbUsers” SelectedValuePath=”Name” />
<TextBox Name=”tbUserName” Text=”{Binding ElementName=cbUsers, Path=SelectedValue}” />

When you add UpdateSourceTrigger=Explicit to the TextBox, you can control the updating by telling the binding mechanism to update.
<TextBox Name=”tbUserName” Text=”{Binding ElementName=cbUsers, Path=SelectedValue, UpdateSourceTrigger=Explicit}” />
How do you do that? That’s where the magic lies :-)
You need to get the BindingExpression for the TextBox:

BindingExpression binding = tbUserName.GetBindingExpression(TextBox.TextProperty);

Then update the linked source( the textbox):

binding.UpdateSource();

bingo


Mar 4 2008   5:56PM GMT

Controlling how the source is updated in a binding



Posted by: Mark Shurmer
WPF

Have you ever wondered how to alter the update frequency of a binding?
Probrably like me, you use the default settings unless you notice something not working
:-)

What am I talking about?
Well, when you have a binding defined to another element for example:

<TextBox Name=”txtFirstOne” />
<TextBox Text=”{Binding ElementName=txtFirstOne, Path=Length” Name=”txtFontSize” />

The second textbox will display the length of the text in the first textbox, as you type. Well actually it doesn’t, as the target is not being updated. To fix that you could add UpdateSourceTrigger=PropertyChanged for this example, and bingo:

<TextBox Text=”{Binding ElementName=txtFirstOne, Path=Length, UpdateSourceTrigger=PropertyChanged” Name=”txtFontSize” />


Feb 27 2008   2:46PM GMT

Save ObservableCollection to Linq for Sql



Posted by: Mark Shurmer
WPF

I described how you create an ObservableCollection from a Linq query (including Linq for Sql amongst others) in a previous post.

A second part of the equation is of course, how do you then save your changes back to the database using Linq?

Of course, you have probrably guessed that it’s not going to be a walk in the park.
What you need to do is go through the object and all sub lists and convert them back into the Linq EntitySet classes. After that they can be saved via SubmitChanges.

Tedious, you bet!
Either I’m missing the point somewhere or the EntityFramework needs to fix this by implementing INotifyCollectionChanged in the EntitySet class


Feb 26 2008   8:25PM GMT

Creating an ObservableCollection from Linq for Sql



Posted by: Mark Shurmer
WPF

Just how do you create an ObservableCollection from a Linq query?
Not easily is the answer.

If you are using WCF as part of your multi-tier strategy, then you can employ a trick that converts your generated Linq for Sql EntitySet classes into ObservableCollection classes. See a previous post of mine for details.

If you are not using WCF, then like me you’re a bit stuck - you seem to have to do it manually. For each access you need to convert it to a non Linq business object class, and crucially all it’s properties that contain lists.
I have here an example from the AdventureWorks database where the Products List is populated from the database into a ProductModel class, and I show how to do this with a couple of sub properties and one sub list (ProductCostHistories).

First here is the Product class, which is a separate class from the Linq generated Product class:

Product class

Here is the ProductModel class which does the interaction with Linq:

ProductModel class


Feb 25 2008   12:06AM GMT

WPF validation via databinding



Posted by: Mark Shurmer
WPF

With v3.5 of the .Net framework, you can now take advantage of the new (well actually quite old) automatic error/validation mechanism.

What do I mean by new/old? I mean that by implementing the IDataErrorInfo interface you can plug into the .Net 3.5 error/validation. When you provide information to the methods of the interface, and tell the WPF binding mechanism to use it, it will magically display a red rectangle around the bound control by specifying the ValidatesOnDataErrors=True binding extension.

An example always helps, so here I have a class that implements the IDataErrorInfo interface:

blog-24feb2008-class.JPG

It provides the this[string propertyName] override. This indexed property gets called by the framework every time a property is updated. This gives you the opportunity to add validation on a per property basis. The interface also has another property Error, which you typically call all of the property validators to get an overall validation message.

An example of how to specify the binding is here:
blog-24feb2008-xaml.JPG