WPF Reflections


March 14, 2008  3:47 PM

DevWeek08



Posted by: MarkWPF
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

March 10, 2008  9:39 PM

Re-using data template across controls



Posted by: MarkWPF
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.


March 9, 2008  6:53 AM

Multi value converter in databinding



Posted by: MarkWPF
C, Databinding, WPF, XAML

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


March 6, 2008  2:45 PM

Explicit control of how the source is updated



Posted by: MarkWPF
Databinding, WPF, 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


March 4, 2008  5:56 PM

Controlling how the source is updated in a binding



Posted by: MarkWPF
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” />


February 27, 2008  2:46 PM

Save ObservableCollection to Linq for Sql



Posted by: MarkWPF
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


February 26, 2008  8:25 PM

Creating an ObservableCollection from Linq for Sql



Posted by: MarkWPF
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


February 25, 2008  12:06 AM

WPF validation via databinding



Posted by: MarkWPF
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 


February 24, 2008  10:11 PM

Databinding with Linq with automatic updates



Posted by: MarkWPF
C, Databinding, SQL, WPF

How do you databind to an EntitySet retreived from a Linq query, via Linq to Sql or Linq to Entities for example?

Well it is very easy to actually bind to it, you simply connect it up using normal Xaml syntax. But what if you want to have updates automatically relected in the UI? That’s something that ObservableCollection does very well, due to it’s implementation of INotifyCollectionChanged. So why didn’t they implement INotifyCollectionChanged in the EntitySet class? Who knows? It would have saved me a load of grief, for starters.

For a list of your different options, see a previous post of mine.

Here I will show how I have got around the problem:

I have a database table called Profiles, which using the Linq for Sql visual designer gives me a class called ProfilePart. As it is a partial class I can have another cs file with my ProfilePart definition and provide my binding implementation.
How do I it? I call the GetNewBindingList() method on the EntitySet, but I need to cache it as I don’t want to do it every time it is accessed.

An example is shown below:

ProfilePart


February 19, 2008  4:08 PM

WPF databinding to Linq



Posted by: MarkWPF
WPF

I think I have (at last) the workaround that gets WPF to bind to objects from Linq (to SQL or Entities or anything…)

The problem is that Linq’s EntitySet class doesn’t implement INotifyCollectionChanged, so when you bind to an object that contains child collection classes you don’t get automatic notification of changes to your collection.

You basically have four choices:

  1. Use a framework like CSLA (and I’m going to look a lot more closely at the v3 of CSLA which supports WPF)
  2. Create another class (and all child classes) and copy data out of the EntitySet into the new class and put that in an ObservableCollection. Then when you save copy it back into a new Linq DataContext (and all the child classes) – do you think yuk like me?
  3. Bind the control to the EntitySet’s GetNewBindingList(), which will dynamically update the control for you
  4. Create a BindingSource object and set it’s DataSource to the EntitySet’s GetNewBindingList() call and then bind the control to the BindingSource

Which you choose depends on the circumstances though of course


Forgot Password

No problem! Submit your e-mail address below. We'll send you an e-mail containing your password.

Your password has been sent to: