News

My Stats

  • Posts - 49
  • Comments - 33
  • Trackbacks - 0

Twitter












Tag Cloud


Recent Comments


Recent Posts


Archives


Post Categories


Image Galleries


 

One of the new data controls in Windows 8 Metro is the ListView. The ListView does the same thing as the ListBox, plus more.  In this post, I’ll build on the TwitterClient, from my previous post: Windows 8 Composition and Content. and show how to refactor the ListBox to a ListView. I’ll also mention a few of the differences between the two controls.

Refactor ListBox to ListView

To save you a little time, I’ll show you the XAML for the ListBox, from my previous post. Then I’ll follow up with changes for making that work as a ListView. Here’s the code for the ListBox:

        <ListBox Height="465" HorizontalAlignment="Left" Margin="5,144,0,0" 
                 Name="PublicTweetListBox" VerticalAlignment="Top" Width="1355"
                 ItemsSource="{Binding Tweets}">
            <ListBox.ItemTemplate>
                <DataTemplate>
                    <StackPanel Orientation="Horizontal" Height="132">
                        <Button>
                            <Image Source="{Binding ImageUrl}" 
                                   Height="73" Width="73" 
                                   VerticalAlignment="Top" Margin="0,10,8,0"/>
                        </Button>
                        <StackPanel Width="370">
                            <TextBlock Text="{Binding Name}" 
                                       Foreground="#FFC8AB14" FontSize="28" />
                            <TextBlock Text="{Binding Text}" 
                                       TextWrapping="Wrap" FontSize="24" />
                        </StackPanel>
                    </StackPanel>
                </DataTemplate>
            </ListBox.ItemTemplate>
        </ListBox>

If you’ve seen the previous post, the code above isn’t anything different – it’s a ListBox with a DataTemplate and bindings to a ViewModel. Here’s how to change the code to switch this to a ListView:

        <ListView Height="465" HorizontalAlignment="Left" Margin="5,144,0,0" 
                 Name="PublicTweetListView" VerticalAlignment="Top" Width="1355"
                 ItemsSource="{Binding Tweets}">
            <ListView.ItemTemplate>
                <DataTemplate>
                    <StackPanel Orientation="Horizontal" Height="132">
                        <Button>
                            <Image Source="{Binding ImageUrl}" 
                                   Height="73" Width="73" 
                                   VerticalAlignment="Top" Margin="0,10,8,0"/>
                        </Button>
                        <StackPanel Width="370">
                            <TextBlock Text="{Binding Name}" 
                                       Foreground="#FFC8AB14" FontSize="28" />
                            <TextBlock Text="{Binding Text}" 
                                       TextWrapping="Wrap" FontSize="24" />
                        </StackPanel>
                    </StackPanel>
                </DataTemplate>
            </ListView.ItemTemplate>
        </ListView>

No need to rub your eyes, all that’s required to change from a ListBox to a ListView is to change all the tag names that say ListBox to ListView.  Besides a name, there’s more that changes, which I’ll discuss next.

Advantages of ListView over ListBox

The biggest advantage of leaving ListBox in Metro is for backwards compatibility with existing XAML app platforms.  However, moving to the new Windows 8 data controls like ListView, GridView, etc. give you some advantages.  Windows 8 data controls have inherent support for the type of visual feedback associated with touch apps. For example, a feature called snap grid causes the list to reposition a list item into view if you stopped panning when that list item is not fully in view.  Another feature is inertia, where the grid keeps scrolling based on the speed of the pan.

Note: The new data/list controls have built-in behaviors, such as snap grid and inertia that are based on animations.

In addition to the visual feedback provided by the new Windows 8 controls, you also have more functionality exposed through the control’s APIs.  The ListView control derives from a new class, ListViewBase, and both ListViewBase and ListBox derive from Selector:

Selector

    ListBox

    ListViewBase

        GridView

        ListView

Through ListViewBase, ListView gets new events, methods, and properties that help it provide the built-in support for Metro look and feel.

By moving from ListBox to ListView, you essentially get all this new functionality for free.  On top of that, you have API support to customize that behavior as you need.

Summary

You saw how easy it is to convert from ListBox to ListView. I followed up with a few comments about the benefits of ListView over ListBox, explaining how ListView gives you all the new Metro look and feel behaviors for free.

@JoeMayo


 

Composition is an integral part of Windows 8 UI design from both aesthetic and logical perspectives. This post modified my previous post, Refactoring Windows 8 Code-Behind to MVVM. adding to the variety of compositional examples.  I’ll start with an explanation of composition in Windows 8, modify the previous code to show the power of composition, and then highlight a few more existing examples of where composition naturally fits into the Windows 8 UI environment.

Understanding Windows 8 Composition

A Windows 8 UI is built like a tree. You have a single root element that surrounds all other elements, multiple branches containing more elements, and finally many leaves that don’t contain any elements. In shorthand, the structure looks something like this:

Root

    Content

        Branch

            Branch

                Leaf

            Branch

                Leaf

                Leaf

        Branch

            Leaf

You might have noticed that I sneaked in an extra element, Content, in the figure above that I hadn’t talked about yet. Nevertheless, Content is necessary and important in Windows 8 development. The figure above is a generalization of the hierarchical relationship between elements.  However, the XAML below, based on the previous post, is a concrete example:

<UserControl x:Class="TwitterClient.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d"
    d:DesignHeight="768" d:DesignWidth="1366">
  
    <Grid x:Name="LayoutRoot" Background="#FF0C0C0C">
        <Button Content="Refresh Public Tweets" Height="72" Width="365" 
                HorizontalAlignment="Left"  Margin="500,66,0,0" 
                Name="RefreshButton" VerticalAlignment="Top"
                Command="{Binding RefreshCommand}"/>
        <ListBox Height="465" HorizontalAlignment="Left" Margin="5,144,0,0" 
                 Name="PublicTweetListBox" VerticalAlignment="Top" Width="1355"
                 ItemsSource="{Binding Tweets}">
            <ListBox.ItemTemplate>
                <DataTemplate>
                    <StackPanel Orientation="Horizontal" Height="132">
                        <Image Source="{Binding ImageUrl}" 
                               Height="73" Width="73" 
                               VerticalAlignment="Top" Margin="0,10,8,0"/>
                        <StackPanel Width="370">
                            <TextBlock Text="{Binding Name}" 
                                       Foreground="#FFC8AB14" FontSize="28" />
                            <TextBlock Text="{Binding Text}" 
                                       TextWrapping="Wrap" FontSize="24" />
                        </StackPanel>
                    </StackPanel>
                </DataTemplate>
            </ListBox.ItemTemplate>
        </ListBox>
    </Grid>   
</UserControl>

The example above gives a better idea of the compositional relationship between elements and how they form a tree that is visually identifiable through proper spacing of elements. UserControl is the Root element and Grid is the Content element for Root.  Subsequent elements form a hierarchy, further displaying the compositional nature of Windows 8 UI development.

Since the examples in this post are based on the previous post, you might find it useful to have a few tips on getting from there to here, which is discussed next.

Reusing Previous Code

Over the past couple of posts, I’ve renamed the same project to something new.  This is more tedious than necessary, so I’ll just rename the project one more time to something more generic, like TwitterClient. If you’re thinking, “Oh no, not another Twitter client!”, don’t worry. It’s just a sample program – and besides, no one will ever use it.

Here’s a quick walk-through of the file system part of the rename:

  1. Make a copy of RefactorToMVVM folder in Windows Explorer and rename it to TwitterClient.
  2. In the new TwitterClient folder, rename the solution file, RefactorToMVVM.sln, to TwitterClient.sln.
  3. Unhide files and rename RefactorToMVVM.v11.suo to TwitterClient.v11.suo (Alternatively delete because VS11 recreates it for you).
  4. Rename the project folder, RefactorToMVVM, to TwitterClient.
  5. In the new TwitterClient project folder, rename the project file, RefactorToMVVM.csproj, to TwitterClient.csproj.

Now your file names are up-to-date, you’ll need to change a couple more items in the solution. To get started on this part, go back to the TwitterClient solution folder and double-click on TwitterClient.sln to open the solution. You’ll see an error saying that VS can’t open the RefactorToMVVM project and that’s okay because you intentionally renamed it – meaning that the solution file won’t be able to find the project file under it’s new name. Click OK for the error message box that appears. The following steps fix the project load problem and take you through the rest of the renaming:

  1. After the solution loads, right-click on the grayed-out RefactorToMVVM project and select Remove.
  2. Right-click on the solution, select Add, Existing Project and an Add Existing Project window will appear.
  3. Navigate to the TwitterClient solution, down to the TwitterClient project, select TwitterClient.csproj and click OK. The new project will load.
  4. Under the TwitterClient project, double-click Properties to open the Properties configuration page.
  5. On the Properties Application tab, change both the Assembly name and Default namespaces to TwitterClient.
  6. Open Tweet.cs (or any code file), select RefactorToMVVM, type Ctrl+R+R, and rename to TwitterClient. Select preview, comments, and strings options and observe all the places in code where the change is made.  Click Apply when you’re ready to make the changes.
  7. Double-click the Package.appxmanifest file, which opens the Package configuration window.
  8. On the Application UI tab, change Display Name to TwitterClient, Entry Point to TwitterClient.App, and Description to Client Application for Twitter.
  9. On the Packaging tab, change Package Display Name to TwitterClient.
  10. Save and close Package.appxmanifest.
  11. The visual designer for Package.appxmanifest doesn’t let you change everything and there’s one more item to remember. Right-click on Package.appxmanifest, select Open With, select XML Editor, and click OK.
  12. Under /Applications/Application, change the Executable attribute to TwitterClient.exe.

Before finishing, press F7 to build the solution. If you have errors, it’s most likely because of the naming changes done previously. So, it would be useful to retrace your steps if the error message doesn’t lead you to the answer right away.  Now that we have a new renamed solution/project, we can proceed to an in-depth discussion of Composition and Content by adding a button the the tweet list.

Adding a Button

Here, we’re not going to just add a button, we’re going to examine how a button supports composition through its Content property. You’ll see attribute content, element content, and a cool trick that makes it easy to code compositional content in XAML.

If you want a simple button with text, you can use the Content attribute, like this:

<Button Content="{Binding Name}" />

The XAML Content attribute corresponds to a Content property of the Button class. Your first thought, upon seeing the Content property on a Button, might be to ask, “Why isn’t this property named Text?” That’s a logical question, especially if you’ve been using Windows Forms, ASP.NET, or one of many other UI frameworks. Actually, Windows 8 is closer to both Silverlight and WPF in their view of composition and content.

The primary rationale for content is because text isn’t the only object you can display on a button. You can add different types of UI elements to a button by assigning those items to the Content property. In previous frameworks, that don’t support content, you would have needed to slog through extra code to create a special button. With Windows 8, you only need to assign a value to the content property of a given control. Here’s an example for creating a button that contains an image:

                        <Button>
                            <Button.Content>
                                <Image Source="{Binding ImageUrl}" 
                                       Height="73" Width="73" 
                                       VerticalAlignment="Top" Margin="0,10,8,0"/>
                            </Button.Content>
                        </Button>

Above, Button contains an image, which can’t be represented in text, as previously shown via the Content attribute. This example uses Property Element syntax – which is the control type and property name, separated by a dot. The power of this approach to re-defining the appearance of a button can’t be understated – you can see how easy it is to do.

Note: The content property isn’t always named Content. i.e. Types derived from ItemsControl, such as ListBox designate the Items property as their content property.

A control can be decorated with  Windows.UI.Xaml.Markup.ContentPropertyAttribute, specifying what the content property is for that control. In the case of Button, the content property is Content (same name):

    [ContentProperty("Content")]
    public class UserControl : Windows.UI.Xaml.Controls.Control
    {
        // ...

        public UIElement Content { get; set; }

        // ...
    }

This is good information if you’re a control developer, but it’s also interesting because of a special feature of content properties that gives you simpler syntax. More specifically, you can remove the Property Element syntax, like this:

                        <Button>
                            <Image Source="{Binding ImageUrl}" 
                                   Height="73" Width="73" 
                                   VerticalAlignment="Top" Margin="0,10,8,0"/>
                        </Button>

The image  below is a new snapshot of the updated screen, showing how the images look as buttons. As you can see, customizing buttons is very easy.  More to the point, composing custom UI elements is easy via Windows 8 content support.

image

 

 

 

 

 

 

 

While this discussion focused on the Button, many other control types have content properties and support composition the same way.  If you look back at the XAML in the previous section, “Understanding Windows 8 Composition”, you’ll see several more composition examples, including UserControl/Grid, Grid/Elements, ListBox/ListBox.ItemTemplate, and so on.

Summary

This post demonstrated the inherent support for composition in Windows 8 UI development. This capability is supported via content properties.  You saw how Button demonstrates the power of composition and the role of the content property in facilitating composition.  Remember that Button is only an example, and you should understand that other controls have content properties.

@JoeMayo