Publishing to the Windows Store

When your application is complete and you want to share it with the rest of the world (for profit or not), it is time to publish it into the Windows Store. That means you will need a developer’s account. The process itself is straightforward. Using your Microsoft Account, you register for access to the store as a developer. After your registration has been approved, you can reserve your application’s name, establish a price, and upload your packaged application into the store.

Once again, Visual Studio makes this process seamless with development. From within the IDE, you can select Store under the Project menu and execute all the activities needed to go from no account to published application (see Figure 23.25).

Image

FIGURE 23.25 Using the Store menu.

There are several actions available to us from the Store menu:

Image Open Developer Account—To publish into the Windows Store, you’ll need a developer account to get you started.

Image Reserve App Name—All applications within the Windows Store are required to have a unique name. Because the app name may be featured prominently in various pieces of your UI, it is wise to settle on and reserve a name before you even begin development. (You can always change things down the road.)

Image Acquire Developer License—As you build out your application, you will need to run that application within one or more development environments to construct and test your code. And that requires a developer license for each machine that you want to deploy your “in progress” code to.

Image Edit App Manifest—This opens the package manifest window (refer to Figure 23.20).

Image Associate App with the Store—This launches a wizard that will automatically download details from your store account (including your publisher ID, publisher name, and so on) and then include those details into your local app manifest file.

Image Capture Screenshots—Applications should have screenshots included in their Window Store entries to enable potential users/purchasers to see what the app is like before downloading. Selecting this option will run the current project within the emulator and allow you to capture screenshots on your machine as you navigate through the application pages. You will upload them when you publish the application.

Image Create App Packages—An app package is just what it sounds like: it is a package that contains all the components of your application. This is actually what Windows Store users will download when they choose to install your app. Selecting this option will create the appropriate package on your machine so you can upload it to the store later.

Image Upload App Packages—This option enables you to create a new release of your app into the Windows Store with the latest and greatest package.

When your application is finally published, you can expect its landing page to look something like Figure 23.26.

Image

FIGURE 23.26 The Kindle app in the Windows Store.

As a final word, please visit this book’s download site (http://informit.com/title/9780672337369 or just search for the book title on InformIt.com) to get the complete source code for the XAML image viewer application. The final application adds some fit and finish to the walk-through presented here, including an app tile and a restyled rating slider control. Listings 23.1 and 23.2 provide the XAML and C# code for the MainWindow page, and Listings 23.3 and 23.4 provide the XAML and C# code for the ImageDetails page.

LISTING 23.1 The Image Viewer XAML Code: MainPage.xaml


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

    <Grid Background="{StaticResource ApplicationPageBackgroundThemeBrush}">
        <Grid.RowDefinitions>
            <RowDefinition Height="140" />
            <RowDefinition Height="*" />
        </Grid.RowDefinitions>

        <TextBlock x:Name="pageTitle" Grid.Row="0" IsHitTestVisible="false"
                   Style="{StaticResource PageHeaderTextStyle}"
                   Text="{StaticResource AppName}"
                   Margin="50,0,0,50"/>

        <GridView x:Name="ImagesGridView" Grid.Row="1"
                  HorizontalAlignment="Left" VerticalAlignment="Top"
                                          SelectionMode="Single"
                  Padding="120,126,120,50"
                  SelectionChanged="ImagesGridView_SelectionChanged"
                  ItemsSource="{Binding Images}"
                  >
            <GridView.ItemContainerStyle>
                <Style TargetType="GridViewItem">
                    <Setter Property="HorizontalContentAlignment"
                     Value="Stretch"/>
                    <Setter Property="VerticalContentAlignment" Value="Top"/>
                    <Setter Property="HorizontalAlignment" Value="Stretch"/>
                    <Setter Property="VerticalAlignment" Value="Top"/>
                </Style>
            </GridView.ItemContainerStyle>
            <GridView.ItemTemplate>
                <DataTemplate>
                    <Grid HorizontalAlignment="Stretch">
                        <Grid.RowDefinitions>
                            <RowDefinition Height="175"/>
                        </Grid.RowDefinitions>
                        <Image Grid.Row="0" Height="175" Width="275"
                               Source="{Binding Image}"
                               Stretch="UniformToFill"/>
                    </Grid>
                </DataTemplate>
            </GridView.ItemTemplate>

        </GridView>

    </Grid>
</Page>


LISTING 23.2 The Image Viewer XAML Code: MainPage.xaml.cs


using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using Windows.Foundation;
using Windows.Foundation.Collections;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Controls.Primitives;
using Windows.UI.Xaml.Data;
using Windows.UI.Xaml.Input;
using Windows.UI.Xaml.Media;
using Windows.UI.Xaml.Navigation;



namespace XamlImageViewer
{
    /// <summary>
    /// An empty page that can be used on its own or navigated to within a frame.
    /// </summary>
    public sealed partial class MainPage : Page
    {
        private ImageList _imageList;

        public MainPage()
        {
            this._imageList = new ImageList();
            this.DataContext = this._imageList;
            this._imageList.LoadImages();

            this.InitializeComponent();
        }

        /// <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 void ImagesGridView_SelectionChanged(object sender,
           SelectionChangedEventArgs e)
        {
            //Navigate to the next page, passing the selected image along.

            //Cast selected item to ImageFile.
            ImageFile image = (ImageFile)ImagesGridView.SelectedItem;
            this.Frame.Navigate(typeof(ImagePage), image);

        }
    }
}


LISTING 23.3 The Image Viewer XAML Code: ImagePage.xaml


<common:LayoutAwarePage
    x:Name="pageRoot"
    x:Class="XamlImageViewer.ImagePage"
    DataContext="{Binding DefaultViewModel,
         RelativeSource={RelativeSource Self}}"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:XamlImageViewer"
    xmlns:common="using:XamlImageViewer.Common"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d">

    <Page.Resources>
        <ResourceDictionary Source="SliderStyle.xaml"/>
    </Page.Resources>

<Page.BottomAppBar>
    <AppBar x:Name="BottomAppBar1" Padding="10,0,10,0" AutomationProperties.Name="Bottom App Bar">
        <Grid>
            <StackPanel x:Name="AppBarStackPanel" Orientation="Horizontal"
                        Grid.Column="0" HorizontalAlignment="Right">
                    <Button x:Name="SaveButton"
                            Style="{StaticResource SaveAppBarButtonStyle}"
                            Tag="Save"
                        Click="SaveButton_Click" />
                </StackPanel>
        </Grid>
    </AppBar>
</Page.BottomAppBar>
    <!--
        This grid acts as a root panel for the page that defines two rows:
        * Row 0 contains the back button and page title
        * Row 1 contains the rest of the page layout
    -->
    <Grid Style="{StaticResource LayoutRootStyle}">
        <Grid.RowDefinitions>
            <RowDefinition Height="140"/>
            <RowDefinition Height="*"/>
        </Grid.RowDefinitions>

        <!-- Back button and page title -->
        <Grid>
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="Auto"/>
                <ColumnDefinition Width="*"/>
            </Grid.ColumnDefinitions>
            <Button x:Name="backButton" Click="GoBack"
                    IsEnabled="{Binding Frame.CanGoBack, ElementName=pageRoot}"
                    Style="{StaticResource BackButtonStyle}"/>

            <TextBlock x:Name="pageTitle" Grid.Column="1"
                       Text="{StaticResource AppName}"
                       Style="{StaticResource PageHeaderTextStyle}"/>

        </Grid>

        <Grid x:Name="ImageGrid" Grid.Row="1">
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width=".65*" />
                <ColumnDefinition Width=".35*" />
            </Grid.ColumnDefinitions>

            <Image x:Name="SelectedImage" Grid.Column="0"
                   Margin="50,0,25,25"
                   Source="{Binding Image}"/>

            <Grid Grid.Column="1">

                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="100" />
                    <ColumnDefinition Width="*"/>
                </Grid.ColumnDefinitions>
                <Grid.RowDefinitions>
                    <RowDefinition Height="auto" />
                    <RowDefinition Height="auto" />

                </Grid.RowDefinitions>

                <!--Image rating and filename display -->
                <Slider Grid.Row="0" Grid.Column="1" Grid.ColumnSpan="2"
                        x:Name="RatingSlider"
                        TickPlacement="Inline" TickFrequency="1"
                        Minimum="0" Maximum="5"
                        HorizontalAlignment="Left"
                        Orientation="Horizontal" Width="300"
                        Style="{StaticResource RatingSliderStyle}"
                        Margin="15,0,0,0"
                        Value="{Binding Rating}"
                        SnapsTo="Ticks"/>

                <TextBlock Grid.Column="0" Grid.Row="1" Margin="5,5,0,5"
                           Style="{StaticResource BasicTextStyle}"
                           HorizontalAlignment="Left" VerticalAlignment="Center"
                           Height="20">File name:</TextBlock>

                <TextBlock Grid.Column="1" Grid.Row="1"
                           x:Name="FileNameTextBlock"
                           Style="{StaticResource BasicTextStyle}"
                           Margin="5,5,0,5"
                           HorizontalAlignment="Left" Text="{Binding FileName}"
                           Width="auto"/>

            </Grid>
        </Grid>


        <VisualStateManager.VisualStateGroups>

            <!--Visual states reflect the application's view state -->
            <VisualStateGroup x:Name="ApplicationViewStates">
                <VisualState x:Name="FullScreenLandscape"/>
                <VisualState x:Name="Filled"/>

                <!--The entire page respects the narrower 100-pixel margin convention for portrait -->
                <VisualState x:Name="FullScreenPortrait">
                    <Storyboard>
                        <ObjectAnimationUsingKeyFrames
                         Storyboard.TargetName="backButton"
                         Storyboard.TargetProperty="Style">
                            <DiscreteObjectKeyFrame KeyTime="0"
                               Value="{StaticResource PortraitBackButtonStyle}"/>
                        </ObjectAnimationUsingKeyFrames>
                    </Storyboard>
                </VisualState>

                <VisualState x:Name="Snapped">
                    <Storyboard>
                        <ObjectAnimationUsingKeyFrames
                            Storyboard.TargetName="backButton"
                            Storyboard.TargetProperty="Style">
                            <DiscreteObjectKeyFrame
                                KeyTime="0"
                                Value="{StaticResource SnappedBackButtonStyle}"/>
                        </ObjectAnimationUsingKeyFrames>
                        <ObjectAnimationUsingKeyFrames
                            Storyboard.TargetName="pageTitle"
                            Storyboard.TargetProperty="Style">
                            <DiscreteObjectKeyFrame
                                KeyTime="0"
                                Value="{StaticResource
                                SnappedPageHeaderTextStyle}"/>
                        </ObjectAnimationUsingKeyFrames>
                    </Storyboard>
                </VisualState>
            </VisualStateGroup>
        </VisualStateManager.VisualStateGroups>
    </Grid>
</common:LayoutAwarePage>


LISTING 23.4 The Image Viewer C# Code: ImagePage.xaml.cs


using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using Windows.Foundation;
using Windows.Foundation.Collections;
using Windows.Storage;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Controls.Primitives;
using Windows.UI.Xaml.Data;
using Windows.UI.Xaml.Input;
using Windows.UI.Xaml.Media;
using Windows.UI.Xaml.Navigation;



namespace XamlImageViewer
{
    /// <summary>
    /// A page that displays details for a single item within a group while
    /// allowing gestures to flip through other items belonging to the
    /// same group.
    /// </summary>
    public sealed partial class ImagePage :
        XamlImageViewer.Common.LayoutAwarePage
    {
        private ImageFile _imageFile;

        public ImageFile ImageFileInstance
        {
            get { return _imageFile; }
            set { _imageFile = value; }
        }

        public ImagePage()
        {
            this.DataContext = ImageFileInstance;
            this.InitializeComponent();
        }

        /// <summary>
        /// Populates the page with content passed during navigation.
        /// Any saved state is also provided when re-creating a
        /// page from a prior session.
        /// </summary>
        /// <param name="navigationParameter">The parameter value
        /// passed to
        /// <see cref="Frame.Navigate(Type, Object)"/> when this page was
        /// initially requested.
        /// </param>
        /// <param name="pageState">A dictionary of state preserved
        /// by this page during an earlier session.  This will be null
        /// the first time a page is visited.</param>
        protected override void LoadState(Object navigationParameter,
            Dictionary<String, Object> pageState)
        {
            ImageFileInstance = navigationParameter as ImageFile;
            this.DataContext = ImageFileInstance;
        }

        /// <summary>
        /// Preserves state associated with this page in case the
        /// application is suspended or the page is discarded
        /// from the navigation cache.  Values must conform to
        /// the serialization
        /// requirements of <see cref="SuspensionManager.SessionState"/>.
        /// </summary>
        /// <param name="pageState">An empty dictionary to be
        /// populated with serializable state.</param>
        protected override void SaveState(Dictionary<String, Object> pageState)
        {
            //TODO: Derive a serializable navigation parameter
            //and assign it to pageState["SelectedItem"]
        }

        private void SaveButton_Click(object sender, RoutedEventArgs e)
        {
            SaveRating();
        }

        private async void SaveRating()
        {
            var file = await
                KnownFolders.PicturesLibrary.GetFileAsync(_imageFile.FileName);
            var fileProperties = await
                file.Properties.GetImagePropertiesAsync();

            fileProperties.Rating =
                (uint)this.RatingSlider.Value;

            await fileProperties.SavePropertiesAsync();
        }

    }
}


..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset