Adding data to a project template (using C#/VB/C++ and XAML)

5 out of 5 rated this helpful - Rate this topic

In the Grid App and Split App project templates, the code that obtains the data needed for the app is in the SampleDataSource.cs/vb/cpp file. This file represents a sample data source for the app. The SampleDataSource file includes static data that you typically need to replace with dynamic data. For example, if your app makes a single request to obtain RSS data, you may want to include this code in SampleDataSource. Including the code there enables you to easily use your own data without changing the data model present in the templates.

You need to be aware of a few things when you add your own data to an app:

  • Groups and items are linked intrinsically. The app expects item data to be organized in groups. You can unlink the two in your own implementation, but you need to modify code to make that implementation work. This topic shows how groups are used in the template data model.
  • When you implement custom data for an app in SampleDataSource, you need to make sure that property names inherent to your custom data are mapped to the property names that are used by the template. You can change the names used by the template, but this requires more code revision. This topic shows a few examples of how to do that.

Items and groups

The grid app and split app are built around data organized as groups of items. The SampleDataSource provided has a collection of groups, each of which is made up of a collection of items.

There are four classes in SampleDataSource: SampleDataCommon, SampleDataItem, SampleDataGroup, and SampleDataSource. Both SampleDataItem and SampleDataGroup extend SampleDataCommon.

SampleDataCommon is a class that holds the properties that are common to both items and groups. These properties include a UniqueID, a title, subtitle, description, and image. This class implements INotifyPropertyChanged by making use of one additional class: BindableBase. BindableBase is a class provided in the common directory. This class is simply an implementation of INotifyPropertyChanged. Feel free to use this base as you extend and build on top of the template.

SampleDataItem extends the SampleDataCommon class by adding two additional properties: content and a pointer back to the group that owns the item. SampleDataGroup extends the SampleDataCommon class by also adding two additional properties. The first of which is the collection of items, aptly named Items. The second is a collection that mirrors the Items property and only has the top 12 items, named TopItems. This collection is used on the GroupedItemsPage as to only show a subset of the items on this page (users can drill into see the entire group on the GroupDetailsPage).

SampleDataSource creates a collection of groups of items with hard-coded static content. It initializes with placeholder data rather than live production data to provide data at both design-time and run-time.

If your data is closely mapped to the schema already provided by SampleDataItem and SampleDataGroup, you can simply remove the hard-coded content in the constructor and instead initialize your data as is appropriate for your app. If you are connecting to live data that might not be available at design-time (or might not load fast enough), remember to wrap any call in the following design-mode check and provide alternate sample data if you want to see data on the design-surface:


        public SampleDataSource()
        {
            if (Windows.ApplicationModel.DesignMode.DesignModeEnabled)
            {
                //Load runtime data here
            }
            else
            {
                //Load sample data here
            }
        }


Binding group and item data to the user interface

In the templates, data is typically bound to the UI through the Default DataContext. In each page data is loaded in the LoadState() event, with a call to the static data member (SampleDataSource) such as the following:var item = SampleDataSource.GetItem((String)navigationParameter); .

Data templates, which are defined in StandardStyles.xaml, are used to format and display multiple instances of data. Each data template binds to properties that are explicitly defined in xaml. Here is one example:


    <!-- Grid-appropriate 250 pixel square item template as seen in the GroupedItemsPage and ItemsPage -->
    <DataTemplate x:Key="Standard250x250ItemTemplate">
        <Grid HorizontalAlignment="Left" Width="250" Height="250">
            <Border Background="{StaticResource ListViewItemPlaceholderBackgroundThemeBrush}">
                <Image Source="{Binding Image}" Stretch="UniformToFill"/>
            </Border>
            <StackPanel 	VerticalAlignment="Bottom" 
Background="{StaticResource ListViewItemOverlayBackgroundThemeBrush}">
                <TextBlock  	Text="{Binding Title}" 
   	Foreground="{StaticResource ListViewItemOverlayForegroundThemeBrush}" 
  	Style="{StaticResource TitleTextStyle}" Height="60" Margin="15,0,15,0"/>
                <TextBlock 	Text="{Binding Subtitle}" 
Foreground="{StaticResource ListViewItemOverlaySecondaryForegroundThemeBrush}" 
Style="{StaticResource CaptionTextStyle}" TextWrapping="NoWrap" Margin="15,0,15,10"/>
            </StackPanel>
        </Grid>
    </DataTemplate>


It is important to understand that the project templates expect certain properties to be present in the data, and these properties are explicitly named in the XAML. In the preceding XAML code for GroupedItemsPage and ItemsPage, you can find properties such as title, subtitle, and image. If your custom app data doesn't use these specific property names, you need to do one of the following:

  • Map your data to these property names (typically in SampleDataSource).
  • Fix all the XAML and code references to these properties in the template code, so that they match the property names used in your data.

Example of binding data to the UI

This section shows how to implement your own data source in a project template. The sample code here uses a request to generate RSS data.

JJ655409.wedge(en-us,WIN.10).gifUpdating SampleDataSource

  1. On the Visual Studio menu, click File > New Project.
  2. In the left pane of the New Project dialog box, expand the Visual C#, Visual Basic, or Visual C++ node.
  3. In the center pane, click either Grid App or Split App.
  4. In the Name box, type DataModelExample, and then click OK.

    The solution is created and the project files appear in Solution Explorer. For more info about the project files, see C#, VB, and C++ project templates for Windows Store apps.

    Important  When you run Visual Studio for the first time, it prompts you to obtain a developer license. For more info, see Get a developer license.

  5. In the DataModel folder, openSampleDataSource.

    In SampleDataSource add the following property and constructor:

    
            public SampleDataCommon()
            {
            }
    
            private DateTime _pubDate;
            public DateTime PubDate
            {
                get { return this._pubDate; }
                set { this.SetProperty(ref this._pubDate, value); }
            }
    
    
    
  6. In SampleDataItem add the following properties:
    
            public SampleDataItem()
            {
            }
    
            private String _author;
            public String Author
            {
                get { return this._author; }
                set { this.SetProperty(ref this._author, value); }
            }
    
            private Uri _link;
            public Uri Link
            {
                get { return this._link; }
                set { this.SetProperty(ref this._link, value); }
            }
    
    
    
  7. In SampleDataGroup add the following constructor:
    
            public SampleDataGroup()
            {
      Items.CollectionChanged += ItemsCollectionChanged;
            }
    
    
    
  8. Remove all the code from the constructor of SampleDataSource.
  9. In SampleDataSource, add the following function:
    
            private async Task<SampleDataGroup> GetFeedAsync(string feedUriString)
            {
                // using Windows.Web.Syndication;
                SyndicationClient client = new SyndicationClient();
                Uri feedUri = new Uri(feedUriString);
    
                try
                {
                    SyndicationFeed feed = await client.RetrieveFeedAsync(feedUri);
    
                    // This code is executed after RetrieveFeedAsync returns the SyndicationFeed.
                    // Process it and copy the data we want into our FeedData and FeedItem classes.
                    SampleDataGroup feedData = new SampleDataGroup();
    
                    feedData.Title = feed.Title.Text;
                    feedData.UniqueId = feed.Id;
                    if (feed.Subtitle != null && feed.Subtitle.Text != null)
                    {
                        feedData.Description = feed.Subtitle.Text;
                    }
                    // Use the date of the latest post as the last updated date.
                    feedData.PubDate = feed.Items[0].PublishedDate.DateTime;
    
                    foreach (SyndicationItem item in feed.Items)
                    {
                        SampleDataItem feedItem = new SampleDataItem();
                        feedItem.Title = item.Title.Text;
                        feedItem.UniqueId = item.Id;
                        feedItem.Group = feedData;
                        feedItem.PubDate = item.PublishedDate.DateTime;
                        feedItem.Author = item.Authors[0].Name.ToString();
                        // Handle the differences between RSS and Atom feeds.
                        if (feed.SourceFormat == SyndicationFormat.Atom10)
                        {
                            feedItem.Content = item.Content.Text;
                            feedItem.Link = new Uri("http://windowsteamblog.com" + item.Id);
                        }
                        else if (feed.SourceFormat == SyndicationFormat.Rss20)
                        {
                            feedItem.Content = item.Summary.Text;
                            feedItem.Link = item.Links[0].Uri;
                        }
                        feedData.Items.Add(feedItem);
                    }
                    return feedData;
                }
                catch (Exception)
                {
                    return null;
                }
            }
        }
    
    
    
  10. Resolve the unused references by adding the two following using statements to the top:
    
    using Windows.Web.Syndication;
    using System.Threading.Tasks;
    
    
    
  11. Add the following methods to SampleDataSource:
    
            public async void SetupData()
            {
                await GetFeedsAsync();
            }        public async Task GetFeedsAsync()
            {
                Task<SampleDataGroup> feed1 =
                    GetFeedAsync("http://windowsteamblog.com/windows/b/developers/atom.aspx");
                Task<SampleDataGroup> feed2 =
                    GetFeedAsync("http://windowsteamblog.com/windows/b/windowsexperience/atom.aspx");
                Task<SampleDataGroup> feed3 =
                    GetFeedAsync("http://windowsteamblog.com/windows/b/extremewindows/atom.aspx");
                Task<SampleDataGroup> feed4 =
                    GetFeedAsync("http://windowsteamblog.com/windows/b/business/atom.aspx");
                Task<SampleDataGroup> feed5 =
                    GetFeedAsync("http://windowsteamblog.com/windows/b/bloggingwindows/atom.aspx");
                Task<SampleDataGroup> feed6 =
                    GetFeedAsync("http://windowsteamblog.com/windows/b/windowssecurity/atom.aspx");
                Task<SampleDataGroup> feed7 =
                    GetFeedAsync("http://windowsteamblog.com/windows/b/springboard/atom.aspx");
                Task<SampleDataGroup> feed8 =
                    GetFeedAsync("http://windowsteamblog.com/windows/b/windowshomeserver/atom.aspx");
                // There is no Atom feed for this blog, so we use the RSS feed.
                Task<SampleDataGroup> feed9 =
                    GetFeedAsync("http://windowsteamblog.com/windows_live/b/windowslive/rss.aspx");
                Task<SampleDataGroup> feed10 =
                    GetFeedAsync("http://windowsteamblog.com/windows_live/b/developer/atom.aspx");
                Task<SampleDataGroup> feed11 =
                    GetFeedAsync("http://windowsteamblog.com/ie/b/ie/atom.aspx");
                Task<SampleDataGroup> feed12 =
                    GetFeedAsync("http://windowsteamblog.com/windows_phone/b/wpdev/atom.aspx");
                Task<SampleDataGroup> feed13 =
                    GetFeedAsync("http://windowsteamblog.com/windows_phone/b/wmdev/atom.aspx");
    
                this._allGroups.Add(await feed1);
                this._allGroups.Add(await feed2);
                this._allGroups.Add(await feed3);
                this._allGroups.Add(await feed4);
                this._allGroups.Add(await feed5);
                this._allGroups.Add(await feed6);
                this._allGroups.Add(await feed7);
                this._allGroups.Add(await feed8);
                this._allGroups.Add(await feed9);
                this._allGroups.Add(await feed10);
                this._allGroups.Add(await feed11);
                this._allGroups.Add(await feed12);
                this._allGroups.Add(await feed13);
            }
    
    
    
  12. Update the constructor to load the data by adding the following code:
    
            public SampleDataSource()
            {
                SetupData();
            }
    
    
    
  13. Click Build > Build solution, or press F7 to make sure the solution builds without error.

For more info about the above code, see Part 5: Create a blog reader (Windows Store apps using C#/VB and XAML). To implement these changes in the UI, see one of the following sections:

  • Binding example data to the UI in the Split App template.
  • Binding example data to the UI in the Grid App template.

JJ655409.wedge(en-us,WIN.10).gifBinding example data to the UI in the Split App template

  1. To use the example code in the Split App project template, open ItemsPage.xaml.
  2. Change the subtitle property to show the published date. Right-click the GridView and open the context menu. Select Edit Additional Templates > Edit Generated Items (ItemTemplate) > Edit a copy.

    A dialog appears. In the Name field type: "ItemsPageLandscapeItemTemplate"

  3. You'll see a template generated and added to the page. From here click the subtitle as you are now in template editing mode. After the subtitle is selected, click the advanced property marker next to text and select Create Data binding.
  4. On the dialog that appears select PubDate and click OK.
  5. The template should now show the following and will be in the page resources at the top of the file:
    
            <DataTemplate x:Key="ItemsPageLandscapeItemTemplate">
                <Grid HorizontalAlignment="Left" Width="250" Height="250">
                    <Border Background="{StaticResource ListViewItemPlaceholderBackgroundThemeBrush}">
                        <Image 	Source="{Binding Image}" Stretch="UniformToFill" 
     				AutomationProperties.Name="{Binding Title}"/>
                    </Border>
                    <StackPanel 	VerticalAlignment="Bottom" 
     				Background="{StaticResource ListViewItemOverlayBackgroundThemeBrush}">
                        <TextBlock Text="{Binding Title}" 
     				 Foreground="{StaticResource ListViewItemOverlayForegroundThemeBrush}" 
     				 Style="{StaticResource TitleTextStyle}" Height="60" Margin="15,0,15,0"/>
                        <TextBlock Text="{Binding PubDate}" 
     			   Foreground="{StaticResource ListViewItemOverlaySecondaryForegroundThemeBrush}" 
     		           Style="{StaticResource CaptionTextStyle}" TextWrapping="NoWrap" 
     			   Margin="15,0,15,10"/>
                    </StackPanel>
                </Grid>
            </DataTemplate
    
    
    
  6. Exit the template scope by double-clicking outside of the page.
  7. Repeat the process for the portrait and snapped view. In the device pane click the Snapped view. Repeat steps 3-8 for the ListView (this time calling the template ItemsPageSnappedItemTemplate.
  8. The template should now show the following and will again be in the page resources at the top of the file:
    
            <DataTemplate x:Key="ItemsPageSnappedItemTemplate">
                <Grid Margin="6">
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="Auto"/>
                        <ColumnDefinition Width="*"/>
                    </Grid.ColumnDefinitions>
                    <Border Background="{StaticResource ListViewItemPlaceholderBackgroundThemeBrush}" 
     			   Width="60" Height="60">
                        <Image Source="{Binding Image}" Stretch="UniformToFill"/>
                    </Border>
                    <StackPanel Grid.Column="1" Margin="10,0,0,0">
                        <TextBlock 	Text="{Binding Title}" Style="{StaticResource ItemTextStyle}" 
     				  	MaxHeight="40"/>
                        <TextBlock 	Text="{Binding PubDate}" 
     					Style="{StaticResource CaptionTextStyle}" TextWrapping="NoWrap"/>
                    </StackPanel>
                </Grid>
            </DataTemplate>
    
    
    
  9. In SplitPage.xaml, we need to make a few more updates.
  10. First we'll fix the ItemTemplate used for the ListView as we did before.
    1. Right click the ListView and bring up the context menu. Select Edit Additional Templates > Edit Generated Items (ItemTemplate) > Edit a copy.
    2. A dialog appears. In the name field type: ListViewItemTemplate.
    3. You'll see a template generated and added to the page. From here click the subtitle as you are now in template editing mode. After the subtitle is selected, click the advanced property marker next to text and select Create Data binding… On the dialog that appears select Author and hit ok.
    4. Click the description as you are now in template editing mode. After the subtitle is selected, click the advanced property marker next to text and select Create Data binding. On the dialog that appears select PubDate and click OK.
    5. Exit template scope by double clicking outside of the page.
  11. Now we need to do the same thing for the portrait and snapped view. In the device pane click the Snapped view. Now repeat the above substeps for the ListView (this time naming the template "ListViewItemTemplateSnapped".
  12. To update the detail portion, click the subtitle below the title and again using the data binding dialog, bind to the Author property.
  13. Save the project and press F5 to debug the app.

    You see the page title immediately, but there's a short delay while the feed data is retrieved. When all the promises are fulfilled, you see each blog in the home page. click one of the blogs to see the blog posts in master/detail view.

JJ655409.wedge(en-us,WIN.10).gifBinding example data to the UI in the Grid template

  1. To use the example code in the Grid App template, open GroupedItemsPage.xaml.
  2. Change the subtitle property to show the published date.
  3. Right click the GridView and bring up the context menu. Select Edit Additional Templates > Edit Generated Items (ItemTemplate) > Edit a copy.
  4. A dialog appears. In the name field type: GroupedItemsPageLandscapeItemTemplate.
  5. You'll see a template generated and added to the page. click the subtitle as you are now in template editing mode. After the subtitle is selected, click the advanced property marker next to text and select Create Data binding.
  6. On the dialog that appears select Author and click OK.
  7. Exit template scope by double clicking outside of the page.
  8. Repeat the process for the portrait and snapped view. In the device pane click the Snapped view. Now repeat steps 3-8 for the ListView (this time calling the template GroupedItemsPageSnappedItemTemplate.
  9. The template should now show the following and will again be in the page resources at the top of the file:
  10. In GroupDetails.xaml, we need to make a few more updates.
  11. First we'll fix the ItemTemplate used for the GridView as we did before.
    1. Right click the GridView. In the context menu, click Edit Additional Templates > Edit Generated Items (ItemTemplate) > Edit a copy.
    2. A dialog appears. In the Name field type "GridViewItemTemplate" .
    3. You'll see a template generated and added to the page. Click the subtitle as you are now in template editing mode. After the subtitle is selected, click the advanced property marker next to text and select Create Data binding. On the dialog that appears select Author and click OK.
    4. Click the description as you are now in template editing mode. After the subtitle is selected, click the advanced property marker next to text and select Create Data binding. On the dialog that appears select PubDate and click OK.
    5. Now exit template scope by double clicking outside of the page.
  12. Repeat the steps for the portrait and snapped view. In the device pane click the Snapped view. Now repeat the above substeps for the ListView (this time naming the template "ListViewItemTemplateSnapped" (bind description to author).
  13. Open the ItemDetailPage.xaml and find the following lines of code:
    
    <!-- Content is allowed to flow across as many columns as needed -->
    <common:RichTextColumns x:Name="richTextColumns" Margin="117,0,117,47">
    <RichTextBlock x:Name="richTextBlock" Width="560" 
     		 Style="{StaticResource ItemRichTextStyle}" IsTextSelectionEnabled="False">
              <Paragraph>
              		<Run FontSize="26.667" FontWeight="Light" Text="{Binding Title}"/>
                     		<LineBreak/>
                            <LineBreak/>
                            <Run FontWeight="Normal" Text="{Binding Subtitle}"/>                                  
     		</Paragraph>
    
    
    
  14. Change the binding in the above code from Subtitle to Author.
  15. Save the project and press F5 to debug the app.

    You see the page title immediately, but there's a short delay while the feed data is retrieved. When all the promises are fulfilled, you see the items in each blog in the home page. Click a group heading to see the group page, or click an item to see an individual blog post.

 

 

Build date: 3/11/2013

Did you find this helpful?
(1500 characters remaining)
© 2013 Microsoft. All rights reserved.