Learning XAML:  Paving the road to WPF (Windows Presentation Foundation) and Silverlight

Summary

This entry is a continuation of the following blog: http://blogs.msdn.com/brunoterkaly/archive/2009/07/09/all-in-one-wpf-demo.aspx

Full source Code

See the end of this post to get full source code to this sample.

Goals for this Post

To embrace DataTriggers and how they can be used to update the UI based on data.

VS 2010

This blog entry takes a new turn in terms of using Visual Studio 2010 as the dev tool.

*NOTE*
Migration to Visual Studio 2010
  We have re-opened the solution under Visual Studio 2010 and have converted to this new format.

   image

Finish the Application

We’ve managed to do a lot of the hard work. The goal is to continue the application by populating a scrolling listbox.

This is the goal:

image

However, here is how far we got previously

(http://blogs.msdn.com/brunoterkaly/archive/2009/07/09/all-in-one-wpf-demo.aspx).

Notice in the window below we are missing the scrolling items that get populated from the data. Well, we’ve done the data part – we’ve got data loaded and ready to show. The main work that remains is to add some more XAML code to display data to the user.

image

image 

Adding our ListBox code

Our listbox code is now ready to add.
 
 
   1:  <ListBox Name="Master" Grid.Row="2" Grid.ColumnSpan="3" Margin="8"
   2:      ItemsSource="{Binding Source={StaticResource listingDataView}}">
   3:      <ListBox.GroupStyle>
   4:          <GroupStyle 
   5:            HeaderTemplate="{StaticResource groupingHeaderTemplate}"
   6:            />
   7:      </ListBox.GroupStyle>
   8:  </ListBox>

The binding source is “listingDataView", which has been explained in depth previously.

image

 <GroupStyle> and HeaderTemplate

GroupStyle declarations are used to group the data in the listbox. This post won’t cover that. I discussed that in a previous post:

WPF & XAML – ListBoxes with a Grouping Capability

Notice that groupingHeaderTemplate still requires declaration.

image

We need to add this to MainWindow.xaml

   1:  <DataTemplate x:Key="groupingHeaderTemplate">
   2:      <TextBlock Text="{Binding Path=Name}"
   3:                 Foreground="Navy" FontWeight="Bold" FontSize="12"/>
   4:  </DataTemplate>

Still not there

Notice the listbox is not looking like we want it to yet.

Notice that although we’ve added the <DataTemplate> tag, we are still not getting the appropriate listbox interface.

image

Learning XAML:  Understanding Templates

What is missing?

DataTemplates allow us to define the appearance of our listbox.

The answer is simple; we are missing a <DataTemplate>
image 
Flexible Presentation
The WPF data templating model provides you with great flexibility to define the presentation of your data.
Built-In to WPF Controls
WPF controls have built-in functionality to support the customization of data presentation.

There are 4 types of templates:

1. ControlTemplate - Allows you to completely redefine the visual appearance of any control. This type of template is the most powerful.

2. ItemsPanelTemplate - A more simple template that lits your work with the ItemsPanel, which is useful for Listboxes and ComboBoxes.

3. DataTemplate - The most common template to use. It is about the display of objects, such as an Employee or Manager object as an example. It is about displaying content.

4. HierarchicalDataTemplate - A form of the DataTemplate optimized for hierarchical data.

The Raw Data – used in ListBox

Before we get into the details of how the visual interface is generated, let’s take a look at the raw data.

   1:  AuctionItem camera = new AuctionItem("Digital camera - good condition", ProductCategory.Electronics, 300, 
   2:                                     new DateTime(2005, 8, 23), userAnna, SpecialFeatures.None);
   3:  AuctionItem snowBoard = new AuctionItem("Snowboard and bindings", ProductCategory.Sports, 120, 
   4:                                     new DateTime(2005, 7, 12), userMike, SpecialFeatures.Highlight);
   5:  AuctionItem insideCSharp = new AuctionItem("Inside C#, second edition", ProductCategory.Books, 
   6:                                     10, new DateTime(2005, 5, 29), this.currentUser, SpecialFeatures.Color);
   7:  AuctionItem laptop = new AuctionItem("Laptop - only 1 year old", ProductCategory.Computers, 500, 
   8:                                     new DateTime(2005, 8, 15), userMark, SpecialFeatures.Highlight);
   9:  AuctionItem setOfChairs = new AuctionItem("Set of 6 chairs", ProductCategory.Home, 120, 
  10:                                     new DateTime(2005, 2, 20), userMike, SpecialFeatures.Color);
  11:  AuctionItem myDVDCollection = new AuctionItem("My DVD Collection", ProductCategory.DVDs, 5, 
  12:                                     new DateTime(2005, 8, 3), userMary, SpecialFeatures.Highlight);
  13:  AuctionItem tvDrama = new AuctionItem("TV Drama Series", ProductCategory.DVDs, 40, 
  14:                                     new DateTime(2005, 7, 28), userAnna, SpecialFeatures.None);
  15:  AuctionItem squashRacket = new AuctionItem("Squash racket", ProductCategory.Sports, 60, 
  16:                                     new DateTime(2005, 4, 4), userMark, SpecialFeatures.Highlight);
  17:   

The last parameter passed to the AuctionItem constructor indicates “SpecialFeatures”

    public enum SpecialFeatures
    {
        None,
        Color,
        Highlight
    }
The data for each item in the listbox is formatted using a grid. The grid is 2 rows and 3 columns.
image 

The Yellow Star: Introduction

The yellow star (implemented as a polygon) is used to indicate items that are to be “highlighted.”

You will notice that data triggers are used to hide or show this yellow star.

What is about the yellow star?

  • It is not ALWAYS visible. In fact, it starts “Hidden.”
  • It is really a polygon” that spans 2 rows and is in column 1

    image

  • The Yellow Star: How to make it appear and disappear

    As you can see in the diagram above

  • It is not ALWAYS visible. In fact, it starts “Hidden.”
  • It is really a polygon” that spans 2 rows and is in column 1

    image

  • The way to understand the code below is to think of it this way:

    if AuctionItem.SpecailFeatures is “Highlight” Make description red and make the star visible. Also, make the border orange
    if AuctionItem.SpecailFeatures is “Color” Simple make the border blue

     

    image

    The Data Trigger Code

       1:         <DataTemplate DataType="{x:Type src:AuctionItem}">
       2:              <Border BorderThickness="1" BorderBrush="Gray"
       3:                      Padding="7" Name="border" Margin="3" Width="500">
       4:                  <Grid>
       5:                    <Grid.RowDefinitions>
       6:                      <RowDefinition/>
       7:                      <RowDefinition/>
       8:   
       9:                    </Grid.RowDefinitions>
      10:                    <Grid.ColumnDefinitions>
      11:                      <ColumnDefinition Width="20"/>
      12:                      <ColumnDefinition Width="86"/>
      13:                      <ColumnDefinition Width="*"/>
      14:                    </Grid.ColumnDefinitions>
      15:                        
      16:                      <Polygon Grid.Row="0" Grid.Column="0" Grid.RowSpan="2"
      17:                               Fill="Yellow" Stroke="Black" StrokeThickness="1"
      18:                               StrokeLineJoin="Round" Width="20" Height="20"
      19:                               Stretch="Fill"
      20:                               Points="9,2 11,7 17,7 12,10 14,15 9,12 4,15 6,10 1,7 7,7"
      21:                               Visibility="Hidden" Name="star"/>
      22:   
      23:                      <TextBlock Grid.Row="0" Grid.Column="1" Margin="0,0,8,0"
      24:                                 Name="descriptionTitle"
      25:                                 Style="{StaticResource smallTitleStyle}">Description:</TextBlock>
      26:                      <TextBlock Name="DescriptionDTDataType" Grid.Row="0" Grid.Column="2" 
      27:                          Text="{Binding Path=Description}" 
      28:                          Style="{StaticResource textStyleTextBlock}"/>
      29:   
      30:                      <TextBlock Grid.Row="1" Grid.Column="1" Margin="0,0,8,0"
      31:                                 Name="currentPriceTitle"
      32:                                 Style="{StaticResource smallTitleStyle}">Current Price:</TextBlock>
      33:                      <StackPanel Grid.Row="1" Grid.Column="2" Orientation="Horizontal">
      34:                          <TextBlock Text="$" Style="{StaticResource textStyleTextBlock}"/>
      35:                          <TextBlock Name="CurrentPriceDTDataType" 
      36:                              Text="{Binding Path=CurrentPrice}" 
      37:                              Style="{StaticResource textStyleTextBlock}"/>
      38:                      </StackPanel>
      39:                  </Grid>
      40:              </Border>
      41:              <DataTemplate.Triggers>
      42:                  <DataTrigger Binding="{Binding Path=SpecialFeatures}">
      43:                      <DataTrigger.Value>
      44:                          <src:SpecialFeatures>Color</src:SpecialFeatures>
      45:                      </DataTrigger.Value>
      46:                    <DataTrigger.Setters>
      47:                      <Setter Property="BorderBrush" Value="DodgerBlue" TargetName="border" />
      48:                      <Setter Property="Foreground" Value="Navy" TargetName="descriptionTitle" />
      49:                      <Setter Property="Foreground" Value="Navy" TargetName="currentPriceTitle" />
      50:                      <Setter Property="BorderThickness" Value="3" TargetName="border" />
      51:                      <Setter Property="Padding" Value="5" TargetName="border" />
      52:                    </DataTrigger.Setters>
      53:                  </DataTrigger>
      54:                  <DataTrigger Binding="{Binding Path=SpecialFeatures}">
      55:                      <DataTrigger.Value>
      56:                          <src:SpecialFeatures>Highlight</src:SpecialFeatures>
      57:                      </DataTrigger.Value>
      58:                      <Setter Property="BorderBrush" Value="Orange" TargetName="border" />
      59:                      <Setter Property="Foreground" Value="Red" TargetName="descriptionTitle" />
      60:                      <Setter Property="Foreground" Value="Navy" TargetName="currentPriceTitle" />
      61:                      <Setter Property="Visibility" Value="Visible" TargetName="star" />
      62:                      <Setter Property="BorderThickness" Value="3" TargetName="border" />
      63:                      <Setter Property="Padding" Value="5" TargetName="border" />
      64:                  </DataTrigger>
      65:              </DataTemplate.Triggers>
      66:          </DataTemplate>

    The default styling – if the trigger does not get set (AuctionItem.SpecialFeatures == None)

    image

    Notice that the Description, CurrentPrice, etc all have a default style:

    image

    Summary

    All of the source code can be downloaded as a project. The code can be used in VS 2010(Beta1)/VS 2008 development environments.

    I will continue to blog about this sample as well as others. Shoot me an email at bterkaly@microsoft.com to expressyour thoughts.

    Look for “download sample” to get source code.

    Microsoft Web Site with Source

      image911

    image