Partilhar via


DataTemplates in WPF..

Today, I mentioned "DataTemplates" to a new team that is just getting started w/ WPF..  

templates came into the conversation because they were asking about time estimation for developing a few screens; being a developer, I argued that the binding and basic layout was trivial and we mostly should be be concerned with designer's time to decorate the screens (because they had conceptual);  of course this landed in MO ( the "show me!"  state) ... and I dumbly said "surely there is lots of samples on data templates out there" ...

Sadly, I was 1/2 way right..  There are lots of samples that use DataTemplates but none that explain it .. www.beacosta.com is by my favorite WPF data blog and she does have samples on the more advanced DataTemplate concepts ( e.g. DataTemplateSelector) ... but no intro..

So, here is my attempt to get out of the hole I digged this morning .. with out reinventing the wheel...

Straight from the "DataTemplates' overview on MSDN" ...

Data templates are a natural extension of styling controls and elements provided in Windows Presentation Foundation. Just as you can apply a visual Style to a user interface (UI) element, you can apply a DataTemplate that can determine both visual aspects of how the data is presented and how data binding accesses the presented data. By applying different data templates to the same data, you can flexibly change the visual appearance of the data in your application. Data templates can be applied to both Windows Presentation Foundation content controls (for example: Button and Hyperlink) and items controls (for example: ListBox, ComboBox, and Menu). These controls have built-in support for applying such data templates.

Next, from Bea's blog,we steal some assets...  and plug in the article you should read after thiss one .. https://www.beacosta.com/Archive/2005_11_01_bcosta_archive.html

Here she has a master-details sample, which I think is perfect to explain data templates:

We have a planet DataObject, and we use templates to represent it in two different ways: simple text in a listbox ( master ) and detailed view for the selected item in the listbox.  Two templates, same data item, two totally different views ...   It is that simple, I am going to bed.  Ok, here I will show you ..

Downloaded beas' sample... but

  • it is PDC build,
  • used an inline XMLData provider -great for her sample, but I extracted it to prove there is no magic tricks in there, and most importantly
  • I wanted to do it using EID ...

So I decided to only reuse the assets (images + xml data source) ...  

Opened her project and extracted the solarSystemPlants XMLData Provider she had ... onto its own file ...  ( planets.xml in attachment) ...

{Setup}

  1. Open EID -
  2. Create New project -
  3. Save Project As    {optional, but I like to do it}
  4. Project - >  Add Existing Item
  5. navigate to her sample and select all the images
  6. Project - > Add Exiting Item
  7. Navigage to our planets.xml file

{ The (drag & drop) work }

  1. On the Data Palette
    1. Add new Xml Data Source
    2. Click Browse
    3. Select planets.xml 
    4. Click OK
  2. Still on Data Palette
    1. Expand the tree, to see SolarSystemPlants and Planet[n]
    2. Move your mouse over the Planet[n] node
    3. While mouseOver on Planet[n] left click to drag & drop the planet[n]  into scene1.
    4. "Select a Control to represent this data field" should come up ...
    5. Select ListBox
    6. Under Create Data binding, Click OK this will create a oneway binding good enough for this ...
    7. Under Create Data Template,  Uncheck  Planet (which should uncheck all)
    8. Now Check @Name    [which again does tha planet, annoys me a little but we will live with it for now]
    9. Under the Name, enter "PlanetNameOnlyTemplate"
    10. Click OK
  3. In Scene1, now we have a listox item with each planet name populated..  this is the simplest view we can have ( winforms even creates that) ... stick around, we will improve on that ...
  4. From Library, drag a  Content Control into our Scene 1  ( make it relatively big, this is our detailss view )
  5. Right Click on the COntent control, select "Bind To Data"
  6. from Data Sources, select SolarSystemDS
  7. Under fields, expand SolarSystemsDS to Planet [n] and select it
  8. Click Define Data Template
  9. Notice the same screen we saw earlier for Creating a Data Template comes up. 
    1. This time we leave everything checked
    2. For Image property (in planet) , we change it from TextBlock to Image ...
    3. Click OK

[We now have two Data Templates for the Planet XML element; one is a simple, name only view, and the other is the Detailed View]....

in Step 7 above we told the data binding code that we were binding to a Planet; this is right, but we specifically want to bind to the planet selected in the listbox, so lets:

  1. Right Click on Content Control again
  2. Select Bind To Data
  3. Click Element Property
  4. Select the ListBox
  5. Under properties, find Selected Item...   and select it
  6. Click Finish
  7. Run it ...    Project -> Test Project ..

he , i bet you are thinking I messed up  :)  cause all u see is the listbox, now Select a planet from the listbox ...  voila ...

Zero lines of code... and we are wired... master details .. see how the datatemplates helped to create two different UI representations for planet   { yes, it is ugly, we still need the designer} 

One last thing is still bothering me .. The listbox still looks simple... Let's spice it up... what we can do is reuse the details template inside the lisbox.... 

  1. In Scene1, Click XAML Code  [
    1. we have to do this to quickly get around what I think is an EID bug or an I/O error with me.. I need to check on later EID build]
  2. Find the line that says

                <DataTemplate x:Key="PlanetTemplate">

and change it into:

               <DataTemplate DataType="Planet" >

By doing this we are now telling the Data template that it can be used any where a template is needed for type Planet  (and a Key has not been specified)

{sorry next should be #3, but this editor does not have 'continue numbering]

  1. Go back to Design view 

  2. Double Click on the ListBox

  3. In properties palette,

    1. select  "ItemTemplate"

    2. Right click, and select "Clear/Default" -- so we clear it from using the old "PlanetNameOnlyTemplate" ... we are not going to set it to any thing but WPF magically will know it is a Planet XML element and find the template for it ..

    3. Now test it, "Project Test Project" ...

    4. You should get a "Detailed view inside the Listbox" ..pretty neat, similar to how Healthcare demo shows the Patients in the listbox...   those are styled our little sample is not ..

That is it ... You have now seen the power of templates..  No lines of code,  under 15 mins, a nice detailed view inside a listbox ....  The designer can now decorate the template nicely.. and be done with it..

The project with the solution is attached...  [create in July CTP under Windows Vista]

You should now go back to www.beacosta.com and read about DataTemplateSelector and some deeper datatemplate topics ... 

[ I will be back later this week w/ more advanced/ interesting posts, this one at least brought me back into the blog]

 

 

 

 

 

 

 

 

 

 

 

 

DT.zip

Comments