Geeks With Blogs

News
Joe Mayo Devices and Things

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

Posted on Monday, February 6, 2012 10:11 AM LINQ to Twitter , Windows 8 | Back to top


Comments on this post: Windows 8 Composition and Content

No comments posted yet.
Your comment:
 (will show your gravatar)
 


Copyright © Joe Mayo | Powered by: GeeksWithBlogs.net | Join free