Monday, March 04, 2013

Using App Bars to Hide Chrome

Brain Dead Simple Windows RT App Part 2

In Microsoft’s UX Guidelines for Windows Store apps, they talk about reducing “chrome” and hiding it in well known locations (to anyone who uses Windows 8). A couple of those well known locations are the top and bottom App Bars. Microsoft has very specific recommendations on where commands belong on these things. I will violate those standards and put one button on the top and one on the bottom.

App Bars are hidden UI elements that can be used to hide commands that are too chromey for the main canvas. They appear when you:

  • swipe from the top or bottom of the screen
  • right click your mouse
  • press WindowKey + Z

The Changes

The app fails to express my level of enthusiasm, which can very as time goes on. So, I propose that I add the ability to add and remove exclamation points to the greeting as my mood changes.

I will put a button to add an exclamation point to the Top App Bar (in clear violation of the UX guidelines) and a button to remove exclamation point to the Bottom App Bar.

<Page.TopAppBar>
    <AppBar>
        <StackPanel HorizontalAlignment="Right" Orientation="Horizontal">
            <Button Style="{StaticResource AddAppBarButtonStyle}" 
                Click="addPoint_Click"  />
        </StackPanel>
    </AppBar>
</Page.TopAppBar>
<Page.BottomAppBar>
    <AppBar>
        <StackPanel HorizontalAlignment="Right" Orientation="Horizontal">
            <Button Style="{StaticResource RemoveAppBarButtonStyle}" 
                Click="removePoint_Click" 
                IsEnabled="{Binding Path=IsRemovePossible}"  />
        </StackPanel>
    </AppBar>
</Page.BottomAppBar>

The styles are available in \Common\StandardStyles.xaml, you need to find them and uncomment them or copy them to MainPage.xaml’s Page.Resources (like I did):

<!-- These styles along with many other can be found in \Common\StandardStyles.xaml -->
<Style x:Key="AddAppBarButtonStyle" TargetType="ButtonBase" 
    BasedOn="{StaticResource AppBarButtonStyle}">
        <Setter Property="AutomationProperties.AutomationId" 
            Value="AddAppBarButton" />
        <Setter Property="AutomationProperties.Name" Value="Add" />
        <Setter Property="Content"                 Value="&#xE109;" />
    </Style>    
    <Style x:Key="RemoveAppBarButtonStyle" TargetType="ButtonBase" 
            BasedOn="{StaticResource AppBarButtonStyle}">
        <Setter Property="AutomationProperties.AutomationId" 
            Value="RemoveAppBarButton" />
        <Setter Property="AutomationProperties.Name" Value="Remove" />
        <Setter Property="Content" Value="&#xE108;" />
    </Style>        

So here’s the additional code (I put it at the bottom of my MainPage.xaml.cs), what is does really isn’t important for this post, it just needs to do something to prove that everything is working.

private int _exlamationPointCount = 0;

private static string setMessge(int exlamationPointCount)
{
    if (exlamationPointCount > 0)
    {
        return BASE_MESSAGE + new string('!', exlamationPointCount);
    }
    else
    {
        return BASE_MESSAGE;
    }
}

private void addPoint_Click(object sender, RoutedEventArgs e)
{
    HelloMessage = setMessge(++_exlamationPointCount);
    RaisePropertyChanged("HelloMessage");
    RaisePropertyChanged("IsRemovePossible");
}

private void removePoint_Click(object sender, RoutedEventArgs e)
{
    if (_exlamationPointCount >= 1)
    {
        HelloMessage = setMessge(--_exlamationPointCount);
        RaisePropertyChanged("HelloMessage");
        RaisePropertyChanged("IsRemovePossible");
    }
}

// Make it possible to disable Remove Point button when there
// is nothing left to remove
public bool IsRemovePossible
{
    get { return _exlamationPointCount > 0; }
}

Basically, what I’m doing is keeping track of exclamation point count in _exlamationPointCount. When the buttons are click I increment or decrement the count, make a new message with setMessge() and notify that the properties have been changed.

Complete MainPage Code Listings


MainPage.xaml

<Page
        x:Class="HelloWindows.MainPage"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="using:HelloWindows"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        mc:Ignorable="d">

    <Page.Resources>
    <!-- These styles along with many other can be found in 
        \Common\StandardStyles.xaml -->
        <Style x:Key="AddAppBarButtonStyle" TargetType="ButtonBase" 
                BasedOn="{StaticResource AppBarButtonStyle}">
            <Setter Property="AutomationProperties.AutomationId" 
                Value="AddAppBarButton" />
            <Setter Property="AutomationProperties.Name" Value="Add '!'" />
            <Setter Property="Content" Value="&#xE109;" />
    </Style>
    <Style x:Key="RemoveAppBarButtonStyle" TargetType="ButtonBase" 
                BasedOn="{StaticResource AppBarButtonStyle}">
            <Setter Property="AutomationProperties.AutomationId" 
                Value="RemoveAppBarButton" />
            <Setter Property="AutomationProperties.Name" Value="Remove '!'" />
            <Setter Property="Content" Value="&#xE108;" />
        </Style>        
    </Page.Resources>
    <Page.TopAppBar>
        <AppBar>
            <StackPanel HorizontalAlignment="Right" Orientation="Horizontal">
                <Button Style="{StaticResource AddAppBarButtonStyle}" 
                    Click="addPoint_Click"  />
            </StackPanel>
        </AppBar>
    </Page.TopAppBar>
    <Page.BottomAppBar>
        <AppBar>
            <StackPanel HorizontalAlignment="Right" Orientation="Horizontal">
                <Button Style="{StaticResource RemoveAppBarButtonStyle}" 
                    Click="removePoint_Click" 
                IsEnabled="{Binding  Path=IsRemovePossible}"  />
            </StackPanel>
        </AppBar>
    </Page.BottomAppBar>
    <Grid Background="{StaticResource ApplicationPageBackgroundThemeBrush}">
        <TextBlock Text="{Binding Path=HelloMessage}" 
            Style="{StaticResource    HeaderTextStyle}" 
            HorizontalAlignment="Center" VerticalAlignment="Center" />
    </Grid>
</Page>

MainPage.xaml.cs

using System.ComponentModel; using Windows.UI.Xaml; using Windows.UI.Xaml.Controls; using Windows.UI.Xaml.Navigation; namespace HelloWindows { /// <summary> /// An empty page that can be used on its own or navigated to within a Frame. /// </summary> public sealed partial class MainPage : Page, INotifyPropertyChanged { public event PropertyChangedEventHandler PropertyChanged; private const string BASE_MESSAGE = "Hello Windows"; public MainPage() { this.InitializeComponent(); HelloMessage = setMessge(_exlamationPointCount); this.DataContext = this; } private void RaisePropertyChanged(string propertyName) { if (PropertyChanged != null) { PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); } } public string HelloMessage { get; set ; } /// <summary> /// Invoked when this page is about to be displayed in a Frame. /// </summary> /// <param name="e">Event data that describes how this page was reached. /// The Parameter /// property is typically used to configure the page.</param> protected override void OnNavigatedTo(NavigationEventArgs e) { } private int _exlamationPointCount = 0; private static string setMessge(int exlamationPointCount) { if (exlamationPointCount > 0) { return BASE_MESSAGE + new string('!', exlamationPointCount); } else { return BASE_MESSAGE; } } private void addPoint_Click(object sender, RoutedEventArgs e) { HelloMessage = setMessge(++_exlamationPointCount); RaisePropertyChanged("HelloMessage"); RaisePropertyChanged("IsRemovePossible"); } private void removePoint_Click(object sender, RoutedEventArgs e) { if (_exlamationPointCount >= 1) { HelloMessage = setMessge(--_exlamationPointCount); RaisePropertyChanged("HelloMessage"); RaisePropertyChanged("IsRemovePossible"); } } // Make it possible to disable Remove Point button when there // is nothing left to remove public bool IsRemovePossible { get { return _exlamationPointCount > 0; } } } }

My Brain Dead Simple Windows RT App: The Series

No comments: