Bulb Flash:- Some practical WPF MVVMLight tips!

One of our major projects recently used WPF 4.0 with MVVM pattern.We used the MVVM Light Toolkit for implementing the MVVM Pattern.

The MVVM Light Toolkit definitely has a lot to offer to make your life easier but the documentation is not exemplary!

Few things we learnt down the road as we came to a close on the project are

1. You are better off using the ViewModalLocator. We didn’t use it initially and realized that our ViewModels are not getting Disposed, multiple view models are getting created especially when using the “Commanding” feature!

2. When using Commands , if you are not using the ViewModalLocator, try not to set the IsDataSource property as it will change the DataContext of your screen to the new ViewModel and there will be inconsistency during commanding as previously set variables will not be available in the new VM. Or if you do need to set the IsDataSource property send all data needed by the command handler as arguments( because previously set data will not be available to the new VM)

3. You need a default empty constructor in all your ViewModels or your XAML screens commands won’t work(They instantiate the empty construtor)

4. You can pass event args parameters in commands using PassEventArgsToCommand="True" in your EventToCommand XAML

5. When using messaging use the method overload Send<TMessage>(TMessage message, object token).Using the token to register and send messages ensures it is delivered only to valid subscribers!

6. Every time you register for an event using the Messenger.Default.Register….ensure you Unregister also using the Messenger.Default.Unregister or else you might have memory leaks!!

Will try to write more elaborate posts detailing out these and more issues .Meanwhile drop a note at anshulee@cennest.com if you have any queries/ need more tips related to MVVM…

Until then!

Cennest!

Code for Keeps:- Store Retrieve image to/from Database

One of our early blogs was about extracting images from databases, websites and showing them on the screen.

The blog(see it here) dealt with

a) Retrieving images from the www

b) Retrieving images from the database when retrieved as a binary.

We realized there are some more scenarios to take care of here

c) Save Image to the database as a byte[]

public Byte[] BufferFromImage(BitmapImage imageSource)
     {
         MemoryStream memStream = new MemoryStream();
         JpegBitmapEncoder encoder = new JpegBitmapEncoder();
         encoder.Frames.Add(BitmapFrame.Create(imageSource));
         encoder.Save(memStream);
         return memStream.GetBuffer();
         
     }

d) Retrieve Image from byte[]( When you use Entity Framework with the Image database type you would get it back as a byte[])

public BitmapImage ConvertToImage(byte[] rawImageData)
  {
      MemoryStream stream = new MemoryStream(rawImageData);
      stream.Position = 0;
      BitmapImage bi = new BitmapImage();
      bi.BeginInit();
      bi.StreamSource = stream;
      bi.EndInit();
      return bi; 
  }
If you see any more scenarios do add comments and lets complete this list…
Cennest!

WPF/Silverlight Canvas Vs Single Cell Grid

I’ve often been asked the question of when should we use a Canvas and when a Single Celled Grid….

This is a snapshot of the an MSDN article . Our inputs are marked as [Cennest:]. The source can be read at  http://msdn.microsoft.com/en-us/magazine/ff646962.aspx

A single-cell Grid is just like a regular Grid except without any row or column definitions. If the Grid has only one cell, you can put multiple elements into the Grid cell and you don’t use any of the Grid’s attached properties to indicate rows or columns.

Initially, using a Canvas or a single-cell Grid seems very similar. Regardless which one you use for vector graphics, Line, Polyline, Polygon and Path elements will be positioned relative to the upper-left corner of the container based on their coordinate points.

The difference between the Canvas and the single-cell Grid is in how the container appears to the rest of the layout system. WPF and Silverlight incorporate a two-pass, top-down layout where every element interrogates the size of its children and is then responsible for arranging its children relative to itself. Within this layout system, the Canvas and the single-cell Grid are very different:

  • To its children, the Grid has the same dimensions as the dimensions of its own parent. These are usually finite dimensions, but the Canvas always appears to have infinite dimensions to its children.
  • The Grid reports the composite size of its children to its parent. 
However, the Canvas always has an apparent size of zero, regardless of the children it contains.

[Cennest:- This has an impact when you try to put the canvas in a Scrollviewer and think that the ScrollViewer will automatically show Scrollbars if the canvas starts exceeding the height and width. However you are zapped when the scroll bars just don’t show up…this is because the canvas notified its height and width as 0 to the scrollviewer which then happily did not show any scrollbars!!.

A workaround for this if you still want to use the scrollbar is to create a Custom Canvas control and override its MeasureOverride property. See this sample]

Suppose you have a bunch of Polygon elements that form some kind of cartoon-like vector graphics image. If you put all these Polygon elements in a single-cell Grid, the size of the Grid is based on the maximum horizontal and vertical coordinates of the polygons. The Grid can then be treated as a normal finite-sized element within the layout system because its size properly reflects the size of the composite image. (Actually, this works correctly only if the upper-left corner of the image is at the point (0, 0), and there are no negative coordinates.)

Put all those polygons in a Canvas, however, and the Canvas reports to the layout system that it has a size of zero. In general, when integrating a composite vector graphics image into your application, you almost certainly want the behavior of the single-cell Grid rather than the Canvas.

So is the Canvas entirely useless? Not at all. The trick is to use the peculiarities of the Canvas to your advantage. In a very real sense, the Canvas doesn’t participate in layout. Hence, you can use it whenever you need to transcend layout—to display graphics that break the bounds of the layout system and float outside it. By default the Canvas doesn’t clip its children, so even if it is very small, it can still host children outside its bounds. The Canvas is more of a reference point for displaying elements or graphics than it is a container

 

Hope this makes things a bit clearer!

Till next time!

Cennest!

Commanding within DataTemplates in MVVM!

A quick post about setting commands within DataTemplates when using the MVVM pattern!

When you are inside a DataTemplate the DataContext is changed to the  the current item, so to access the command you will need to use the “relative source”

Something like

 <Button Content="Delete" Width="Auto" 
Command="{Binding DataContext.RemoveCommand, 
RelativeSource={RelativeSource FindAncestor,
 AncestorType={x:Type ItemsControl}}}" 
CommandParameter="{Binding}">

Hope this real quick note helps save you some time!!

Until next time!

Cennest!

Multiple Level Master Detail Binding in WPF(XAML)

I’ve seen a couple of developers fumble with a LOT of Code when asked to implement a 2-3 level Master –detail form.

So we put together a bit of code to showcase how easily it can be done with virtually no code (alteast no code behind!!) in WPF

Consider the following problem statement:

Create a form which lists a set of families in a dropdown.(Level 1)

Depending on the family selected list the members of the family. List the sons and daughters in a dropdown(Level 2)

 

Depending on the son or daughter selected, list their friends in a dropdown(Level 3)

So your form should look like

To make things more interesting, all this information about the families comes from this XML Document. Family.xml

So how do we do this in WPF?.

The following 4 Step process should suffice!!

1.       Create an XML Data provider for the XML  Document and set the XPath to the Family Node

<XmlDataProvider x:Key=”dataSource” Source=”Family.xml” XPath=”/Families/Family”></XmlDataProvider> 

2.       Create the UI in 2 layers  i.e there should be 3 grids let’s call them the  FamilyGrid, Son Grid and Daughter Grid

So the structure is

<Grid x:Name=”FamilyGrid”>

<..Place the Level 1 controls here…i.e Family combobox, Father and Mother text blocks–>

                <Grid  x:Name=”SonGrid”>

<.. Place the Level 2 and Level 3 controls here..i.e the “Son” Combo box followed by the Son’s friends..>

                </Grid>

<Grid  x:Name=”DaughterGrid”>

<.. Place the Level 2 and Level 3 controls here..i.e the “Daughter” Combo box followed by the Daughter’s friends..>

</Grid>

                </Grid>

3.       Set the DataContexts of the Grids

a.       Family Grid: Set the DataContext to the Family Node

<Grid x: Name=”FamilyGrid” DataContext=”{Binding Source={StaticResource  dataSource}}”>

b.      Son Grid: Set the DataContext to the “Son” Node within the current Binding

<Grid x:Name=”SonGrid” DataContext=”{Binding XPath=Children/Sons/Son}”>

c.       Daughter’s Grid: Set the DataContext to the “Daughter” Node within the current Binding

<Grid x:Name=”DaughterGrid” DataContext=”{Binding XPath=Children/Daughters/Daughter}”>

4.       Bind the Comboboxes to the required fields and set the IsSynchronizedWithCurrentItem= true

 As Highlighted above the key points here are

·         The DataContexts of the Grids which are set to the level of information which we want to show. Whenever a control does an “ItemSource= {Binding…}, the compiler will travel up the UI Heirarchy to find the first not- null data context.So it helps to set the datacontext at the “container” level if mutiple controls need to refer to a common data source.

 

 Since we have a hierarchy of grids and the family grid refers to the /Families/Family Node, we just need to keep setting the DataContext={Binding , XPath= <the XPath to the Node following the family node>}. DataContext={ Binding…} will take you to the /Families/Family node and the XPath will take you to your desired node

 

·         The Property IsSynchronizedWithCurrentItem which is being set to true in the comboboxes is the key here.When you bind a set of data to a value select control and set IsSynchronizedWithCurrentItem = true, what you are saying is “From this point onwards consider this data item as the selected item and refer to it for data for the ensuing controls”

 

So when you select a family in the family combobox, and make it the “Current Selected” data item, the other comboboxes will refer to the data present in the selected family at the specified path , so Family/Son will search for the Son node within the selected Family

 So using a combination of DataContexts to refer to different levels of data and IsSynchronizedWithCurrentItem to set the currently selected data you can go upto n levels of master details binding,and you wudn’t have written a single line of code in you .cs fileJ

  You can find the solution for the above example here MasterDetailBinding.zip.

 Happy Detailing!

Cennest

Improving WPF/Silverlight- WCF Communication!

While working on a recent assignment related to establishing and optimizing duplex communication with Silverlight and WCF,we learnt quite a lot of new concepts like HttpPollingDuplex binding  with multiple messages mode Http Long Polling designs etc.

While most of these concepts were new we did get a bulb flash on how to improve basic WPF/Silverlight WCF communication!!

All WPF/ Silverlight applications share the same threading model . They have a UI thread and a rendering thread. The rendering thread takes care of the background processing while the UI thread takes care of painting the screen, resizing and the overall look and feel. Whatever happens on the UI thread is primarily synchronous and blocks the UI.

Now whenever we need to work with WCF services without blocking the UI we go for asynchronous calls(In Silverlight we have no option anyway), but the mistake we make is we call the WCF service directly from the UI thread(on say a button click). Now since the webmethod was called from the UI thread its Async Event Handler is also executed on the same thread. So this event handler becomes one of the many tasks the UI thread has to be performed and the end result is a slower UI update. An advantage here is that since we are on the UI thread we can update the UI element directly(else we would have to use a dispatcher!)

How else should we do this?:- An ideal way here would be to separate the task of the UI thread and disturb it only when needed i.e when we need to update the UI.

So basically use worker threads to invoke the webservices and handle their responses and use dispatchers  to update the User Interface! So the downside is slightly more complex code to finally update the UI but then you used WPF/Silverlight to get a great and responsive UI..it does come at a cost:-)

Hope this Bulb Flash helps you improve your app performance!!

Until some more flashes!

Cennest

(WPF ListView/ TreeView)Get rid of that default (blue) selection colour!!

This next blog covers a very trivial but important problem. Important because i think almost everyone would want to override this default behavior of WPF and trivial because the solution is actually pretty simple.Atleast its simple now that i know it. It wasn’t so simple for me earlier though;-)

For this blog i feel pictorial rep is going to be the easiest to follow .OK so the problem is this.

I have a List View with ListView Items and everytime i select an item it turns Blue with a white foreground. Customer says i want Gray background and Blue font (weird choice i know..but then Customer is the King!). So how do we do this??

We basically need to tweak the control template of a ListViewItem. Yeah..ListViewItem.. believe me the ListView is not at fault so changing the background, foreground , selection colour etc of the ListView doesn’t help (you can try it if you have the time :-)).

I think Expression Blend is the easiest way to tweak the control template and though as a developer i swear by VS but Blend does get an extra brownie point for this one.. so the following steps help us here. Open Expression Blend, create a new WPF application and put a ListView control on it. Then go on to add a few ListViewItems as follows.

Do this 2-3 times to add 2-3 List view Items.

Next get the control template of the ListViewItem.

This will create a new style for the ListViewItem. It will ask you where you want to create the style. Since this really isn’t your project the hierarchy doesn’t matter, so keep it in the Window itself

OK. Now Open the Window.xaml. You will find a new style under the Resources section.

The Lines i have highlighted are our culprit. You can see a trigger defined for Selection which sets the background and foreground based on dynamic resources picked up depending on the theme of the OS the app is running on.

So change the trigger values to what YOU want

<Trigger Property=”IsSelected” Value=”true”>
        <Setter Property=”Background” TargetName=”Bd” Value=”Gray”/>
        <Setter Property=”Foreground” Value=”Blue”/>
  </Trigger>

But this is not enough. You have created a style and given it a key. Which means that this style is applicable only to those ListViewItems to specifically subscribe to it saying Style={StaticResource ListViewItemStyle1}. This is not what we want. We want all the Items to follow this style. So remove the “x:key= ListViewItemStyle1” from the style definition.

This will make the style applicable to all the UI elements of Target Type= “ListViewItem”(lower in the heirarchy ofcourse)

Now run the app (f5) and select any ListView Item

Now pick up this style definition and paste it in your app.xaml/ window.xaml depending on the heirarchy you want!

This works for ListView/ TreeView … hope it helps you somehow!

Till next time!

Cennest