Tuesday, January 17, 2012

Working with Collections - 21

Working with Collections - 21:

Collections are a more powerful form of arrays. In this lesson we demonstrate an "old style" collection (pointing out its limitations) as well as several of the newer, strongly typed generic collections (List<T> and Dictionary<T1, T2>) utilizing the generics syntax.

Download the source code for Working with Collections

Understanding Event Driven Programming - 23

Understanding Event Driven Programming - 23:

In this lesson we demonstrate how events are utilized in the .NET Framework Class Library specific to WPF and ASP.NET Web Forms applications. In these examples, we see how C# is generated by the IDE to "wire up" a user action or application event to the code that handles that event. The point is that there's a pattern to how .NET works with events and how events drive most Graphical User Interface based applications.

Concluding Thoughts - 24

Concluding Thoughts - 24:

In this final video, Bob talks about approaches to solving common issues that arise for new software developers, where to turn for help, how to search for answers to technical questions, how to ask for help and become part of the .NET community, how to create a personal knowledge base of books and articles, and finally provides a long term path that you can follow to learn more about developing Windows and Web applications.

Import CSV File Into SQL Server Using Bulk Insert – Load Comma Delimited File Into SQL Server

Import CSV File Into SQL Server Using Bulk Insert – Load Comma Delimited File Into SQL Server:

Import CSV File Into SQL Server Using Bulk Insert – Load Comma Delimited File Into SQL Server

Import CSV File Into SQL Server Using Bulk Insert – Load Comma Delimited File Into SQL Server:

Install the Ajax Control Toolkit from NuGet

Install the Ajax Control Toolkit from NuGet:

The Ajax Control Toolkit is now available from NuGet. This makes it super easy to add the latest version of the Ajax Control Toolkit to any Web Forms application.

If you haven’t used NuGet yet, then you are missing out on a great tool which you can use with Visual Studio to add new features to an application. You can use NuGet with both ASP.NET MVC and ASP.NET Web Forms applications. NuGet is compatible with both Websites and Web Applications and it works with both C# and VB.NET applications.

clip_image002

For example, I habitually use NuGet to add the latest version of ELMAH, Entity Framework, jQuery, jQuery UI, and jQuery Templates to applications that I create. To download NuGet, visit the NuGet website at:

http://NuGet.org

Imagine, for example, that you want to take advantage of the Ajax Control Toolkit RoundedCorners extender to create cross-browser compatible rounded corners in a Web Forms application. Follow these steps.

Right click on your project in the Solution Explorer window and select the option Add Library Package Reference.

clip_image004

In the Add Library Package Reference dialog, select the Online tab and enter AjaxControlToolkit in the search box:

clip_image006

Click the Install button and the latest version of the Ajax Control Toolkit will be installed.

Installing the Ajax Control Toolkit makes several modifications to your application. First, a reference to the Ajax Control Toolkit is added to your application. In a Web Application Project, you can see the new reference in the References folder:

clip_image007

Installing the Ajax Control Toolkit NuGet package also updates your Web.config file. The tag prefix ajaxToolkit is registered so that you can easily use Ajax Control Toolkit controls within any page without adding a @Register directive to the page.

<configuration>
<system.web>
<compilation debug="true" targetFramework="4.0" />
<pages>
<controls>
<add tagPrefix="ajaxToolkit"
assembly="AjaxControlToolkit"
namespace="AjaxControlToolkit" />
</controls>
</pages>
</system.web>
</configuration>


You should do a rebuild of your application by selecting the Visual Studio menu option Build, Rebuild Solution so that Visual Studio picks up on the new controls (You won’t get Intellisense for the Ajax Control Toolkit controls until you do a build).



After you add the Ajax Control Toolkit to your application, you can start using any of the 40 Ajax Control Toolkit controls in your application (see http://www.asp.net/ajax/ajaxcontroltoolkit/samples/ for a reference for the controls).



<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="WebForm1.aspx.cs" Inherits="WebApplication1.WebForm1" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title>Rounded Corners</title>

<style type="text/css">

#pnl1 {
background-color: gray;
width: 200px;
color:White;
font: 14pt Verdana;
}

#pnl1_contents {
padding: 10px;
}

</style>

</head>
<body>
<form id="form1" runat="server">
<div>

<asp:Panel ID="pnl1" runat="server">
<div id="pnl1_contents">

I have rounded corners!

</div>
</asp:Panel>

<ajaxToolkit:ToolkitScriptManager ID="sm1" runat="server" />

<ajaxToolkit:RoundedCornersExtender TargetControlID="pnl1" runat="server" />

</div>
</form>
</body>
</html>


The page contains the following three controls:




  • Panel – The Panel control named pnl1 contains the content which appears with rounded corners.


  • ToolkitScriptManager – Every page which uses the Ajax Control Toolkit must contain a single ToolkitScriptManager. The ToolkitScriptManager loads all of the JavaScript files used by the Ajax Control Toolkit.


  • RoundedCornersExtender – This Ajax Control Toolkit extender targets the Panel control. It makes the Panel control appear with rounded corners. You can control the “roundiness” of the corners by modifying the Radius property.



Notice that you get Intellisense when typing the Ajax Control Toolkit tags. As soon as you type <ajaxToolkit, all of the available Ajax Control Toolkit controls appear:



clip_image008



When you open the page in a browser, then the contents of the Panel appears with rounded corners.



clip_image009



The advantage of using the RoundedCorners extender is that it is cross-browser compatible. It works great with Internet Explorer, Opera, Firefox, Chrome, and Safari even though different browsers implement rounded corners in different ways. The RoundedCorners extender even works with an ancient browser such as Internet Explorer 6.



Getting the Latest Version of the Ajax Control Toolkit



The Ajax Control Toolkit continues to evolve at a rapid pace. We are hard at work at fixing bugs and adding new features to the project. We plan to have a new release of the Ajax Control Toolkit each month.



The easiest way to get the latest version of the Ajax Control Toolkit is to use NuGet. You can open the NuGet Add Library Package Reference dialog at any time to update the Ajax Control Toolkit to the latest version.



When things go horribly wrong, and your brother dies as a result

When things go horribly wrong, and your brother dies as a result: This is a technical blog for the most part. I usually talk about all kinds of geek programmer stuff, but today is different. Today I feel that I have to take a moment and discuss the death of my brother...

Building your first Windows Metro style app using C#, C++, or Visual Basic

Building your first Windows Metro style app using C#, C++, or Visual Basic

[This documentation is preliminary and is subject to change.]
A Windows Metro style app is an application tailored for the new Windows user experience introduced inWindows Developer Preview. Here we introduce the essential code and concepts you need to create a Metro style app using C++, C#, or Visual Basic using Extensible Application Markup Language (XAML) to define the UI, and your selected language to write the app logic.
Note  If you’d rather use JavaScript, see Building your first Windows Metro style app using JavaScript.


Objectives

In this topic, we'll take a quick tour of the features that you'll use to build Metro style apps using C++, C#, or Visual Basic. We'll create a simple blog reader that downloads and displays data from an RSS 2.0 or Atom 1.0 feed, and see how to make an app that conveys the right personality. We introduce concepts that are core to the development platform, including Controls, Capabilities, Layout, Templates, and Data Binding. By the time you complete this tutorial, you'll be prepared to start building your own Metro style app using C++, C#, or Visual Basic. This topic should take about 20 minutes to read; however, if you complete each of the exercises, it may take you a little longer.

Hello World

When you create your Metro style app using C++, C#, or Visual Basic, you typically define the UI using XAML, and write your app logic in an associated code behind file in your selected language. You will find the XAML UI framework for Metro style apps using C++, C#, or Visual Basic in the Windows.UI.Xaml.* namespaces of the Windows Runtime. If you've written apps using Windows Presentation Foundation (WPF), Silverlight, or Silverlight for Windows Phone, you're already familiar with this programming model and much of your experience will transfer to creating your Metro style app using C++, C#, or Visual Basic.
The example here shows the XAML that defines the UI for a simple Hello World app and its associated code behind page. Even this simple example shows several concepts that are important to the XAML-based programming model, including partial classes, layout, controls, properties, and events.

    
    
      
        
// C#
namespace HelloWorld
{
    partial class MainPage
    {
        public MainPage()
        {
            InitializeComponent();
        }

        private void HelloButton_Click(object sender, RoutedEventArgs e)
        {
            DisplayText.Text = "Hello World";
        }
    }
}


' Visual Basic
Partial Public Class MainPage

    Public Sub New()
        Me.InitializeComponent()
    End Sub

    Private Sub HelloButton_Click(ByVal sender As Object, ByVal e As RoutedEventArgs)
        DisplayText.Text = "Hello World"
    End Sub

End Class

// C++
MainPage::MainPage()
{
    InitializeComponent();
}

MainPage::~MainPage()
{
}

void HelloWorld::MainPage::HelloButton_Click(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e)
{
    DisplayText->Text = "Hello World";

}

A Hello World app is good place to start. But it doesn't take you very far down the road to profitability, so we'll take a different path as we explore building Metro style apps for Windows Developer Preview. The sample app that we use to get started is a simple blog reader that downloads and displays data from an RSS 2.0 or Atom 1.0 feed. It seems appropriate to use the feed provided by one of several Windows team blogs, the Developing for Windows blog, shown here.
The Developing for Windows blog.

Creating Windows Metro style apps in Visual Studio

In this section, you will learn how to:
  • create a new Windows Metro style project in Microsoft Visual Studio 11 Express for Windows Developer Preview.
Visual Studio is a powerful Integrated Development Environment (IDE) for developing Windows apps. It provides source file management; integrated build, deployment and launching support; XAML, Visual Basic, C#, C++, graphics, and manifest editing; debugging, and more. Visual Studio comes in several editions, but we'll use Visual Studio 11 Express for Windows Developer Preview. You can download it for free along with the Windows Software Development Kit (SDK) for Metro style Apps so that you have everything you need to build, package and deploy your Metro style apps.
To get started creating an application, you can create a new Windows Metro style project using C++, C#, or Visual Basic. Visual Studio 11 Express for Windows Developer Preview includes several templates for Windows Metro style projects that give you a head start on apps using a variety of layouts. The Windows Metro style project template provides the minimum files you need for all Windows Metro style apps.
BR211380.wedge(en-us,WIN.10).gifTo create a new Windows Metro style project
  1. Install Visual Studio 11 Express for Windows Developer Preview. Note that only BUILD conference attendees and MSDN subscribers can currently acquire the tools necessary to build Metro style apps.
  2. Select File > New Project. The New Project dialog box opens.
  3. In the Installed pane, expand Visual C++, Visual C# or Visual Basic.
  4. Select the Windows Metro style template type.
  5. In the center pane, select Application.
  6. Enter a name for the project.Here's a new project being created in Visual Studio 11 Express for Windows Developer Preview.
    Visual Studio New Project dialog.
  7. Click OK. Your project files are created.
When you create your project, Visual Studio creates the project files and displays them in the Solution Explorer pane. Let's look at the files that the Application template creates.
File NameFile Description
AssemblyInfo (.vb or .cs)This file contains the name and version metadata that is embedded into the generated assembly. This file is in C# and Visual Basic projects only.
Package.appxmanifestThis file contains metadata that describes your app, including display name, description, logos, and capabilities.
ImagesThese files are the default logo and splashscreen images that you can replace with your own.
App.xaml, App.xaml.* (.vb, .cs, .cpp)These files specify app-level logic. The App class is required to display the user interface.
MainPage.xamlThis file is the default start page that you use to create the user interface.
MainPage.xaml.* (.vb, .cs, .cpp)This is the code-behind file that contains the logic for the default start page.
MainPage.xaml.hThe header file for MainPage.xaml.cpp. This file is in C++ projects only.
pch.h, pch.cppPrecompiled header files. These files are in C++ projects only.

Specifying app capabilities

In this section, you will learn how to:
  • use capabilities
  • specify app capabilities in the Application Manifest Designer.
A Metro style app runs in a security container with limited access to the file system, network resources, and hardware. Whenever a user installs an app from the Windows Store, Windows looks at the metadata in the Package.appxmanifest file to figure out what capabilities the app needs to function. For example, an app might need to access data from the Internet, documents from the user's Document Library, or the user's webcam and microphone. When the app is installed, it displays to the user the capabilities it needs, and the user must grant permission for it to access those resources. If the app doesn't request and receive access to a resource it needs, it will not be allowed access to that resource when the user runs it.
Here are some common capabilities:
CapabilityNameDescription
Internet (Client)internetClientAllows your app to access the Internet and public networks. Most apps that require Internet access should use this capability.
Internet (Client & Server)internetClientServerAllows your app to access the Internet and public networks, and allows incoming connections from the Internet to your app. Inbound access to critical ports is always blocked. This is a superset of the Internet (Client) capability. You do not need to declare both.
Home/Work NetworkingprivateNetworkClientServerAllows inbound and outbound access from your app to the user's trusted networks such as home and enterprise networks. Inbound access to critical ports is always blocked.
Document Library AccessdocumentsLibraryAllows your app to access the user's Document Library, and to add, change, or delete files. Your app can access only file types that it has declared in the manifest. Your app cannot access Document Libraries on HomeGroup computers.
Picture Library AccesspicturesLibraryAllows your app to access the user's Picture Library, and to add, change, or delete files. It also allows access to Picture Libraries on HomeGroup computers, and picture file types on locally connected media servers.
Video Library AccessvideosLibraryAllows your app to access the user's Video Library, and to add, change, or delete files. It also allows access to Video Libraries on HomeGroup computers, and video file types on locally connected media servers.
Music Library AccessmusicLibraryAllows your app to access the user's Music Library, and to add, change, or delete files. It also allows access to Music Libraries on HomeGroup computers, and music file types on locally connected media servers.
Default Windows CredentialsdefaultWindowsCredentialsAllows an app to connect to intranet resources that require domain credentials.
Shared User CertificatessharedUserCertificatesAllows your app to access software and hardware certificates, such as smart card certificates.
Removable StorageremovableStorageAllows your app to access removable storage devices, such as an external hard drive or USB flash drive, and to add, change, or delete files. Your app can access only file types that it has declared in the manifest. Your app can't access removable storage devices on HomeGroup computers.
LocationlocationAllows your app to access the user's current location.
MicrophonemicrophoneAllows your app to access the user's microphone.
WebcamwebcamAllows your app to access the user's camera.
Text MessagingsmsAllows your app to access text messaging functionality.
Near-field ProximityproximityAllows your app to access the user's near-field communication (NFC) device.

BR211380.wedge(en-us,WIN.10).gifTo add capabilities to an app
  1. In Solution Explorer, double-click Package.appxmanifest. The file opens in the Application Manifest Designer.
  2. In the Application Manifest Designer, select the Capabilites tab.
  3. Select the check box next to each capability that your app needs.
  4. Save and close the file.
When you specify a capability, it's listed in the Package.appxmanifest.xml file under the Capabilities element. You typically set the capabilities in the Application Manifest Designer as we just saw, but if you right-click the file and select View Code, you can see this Capabilites element in the xml.
    
    


Getting data into an app

In this section, you will learn how to:
  • create a custom data class
  • retrieve an RSS or Atom data feed asynchronously.
Now that our app can download data from the internet, we can write the code to get the blog feed into our app. The Developing for Windows blog exposes the full text of its posts in both RSS and Atom form. The blog data that we want to display in our reader app is the title, author, date, and content from each of the latest blog posts.
To start, we need to download the data for each of the posts. Fortunately, the Windows Runtime contains a set of classes that does a lot of the work of processing the feed data for us. We find these classes in the Windows.Web.Syndication namespace. It’s possible to use these classes directly to show the data in the UI. But in our blog reader, we will create our own data classes. This gives us some additional flexibility and allows us to treat RSS and Atom feeds in the same way.
Our blog reader is a simple app, so we need only two data classes. The FeedData class holds info about the RSS or Atom feed. The FeedItem class holds info about individual blog posts that the feed contains. Here's the code for the FeedData and FeedItem classes.
// C#
    public class FeedData
    {
        public string Title { get; set; }
        
        // using System.Collections.ObjectModel;
        private ObservableCollection _Items = new ObservableCollection();
        public ObservableCollection Items
        {
            get
            {
                return this._Items;
            }
        }
    }

    public class FeedItem
    {
        public string Title { get; set; }
        public string Author { get; set; }
        public string Content { get; set; }
        public DateTime PubDate { get; set; }

    }

' Visual Basic
Public Class FeedData
    Public Property Title() As String = String.Empty

    ' Imports System.Collections.ObjectModel
    Private _Items As New ObservableCollection(Of FeedItem)()
    Public ReadOnly Property Items() As ObservableCollection(Of FeedItem)
        Get
            Return Me._Items
        End Get
    End Property
End Class

Public Class FeedItem
    Public Property Title() As String = String.Empty
    Public Property Author() As String = String.Empty
    Public Property Content() As String = String.Empty
    Public Property PubDate() As DateTime

End Class

In the C++ version of the FeedData and FeedItem classes, we implement the ICustomPropertyProvider interface so that data binding works correctly in Windows Developer Preview.
// C++
//
// FeedData.h
// Declaration of the FeedData and FeedItem classes
//

#pragma once

#include "pch.h"
#include 

namespace SimpleBlogReader
{
 // FeedData
 ref class FeedData : public Windows::UI::Xaml::Data::ICustomPropertyProvider, public Platform::IDisposable
    {
    public:
        FeedData();
        void OnPropertyChanged(Platform::String^ propertyName);
         
        // ICustomPropertyProvider interface
        virtual Windows::UI::Xaml::Data::ICustomProperty^ GetCustomProperty(Platform::String^ name);
        virtual Windows::UI::Xaml::Data::ICustomProperty^ GetIndexedProperty(Platform::String^ name, Windows::UI::Xaml::Interop::TypeName typeName);
        virtual Platform::String^ GetStringRepresentation();
        virtual property Windows::UI::Xaml::Interop::TypeName Type { Windows::UI::Xaml::Interop::TypeName get(); }

    private:
  Vector^ _items;
        Platform::String^ _title;

    public:
  property Vector^ Items { Vector^ get();  }
        property Platform::String^ Title { Platform::String^ get(); void set(Platform::String^ value); }

        Object^ TitleGetter(Object^ instance);
    };

 // FeedItem
    ref class FeedItem : public Windows::UI::Xaml::Data::ICustomPropertyProvider, public Platform::IDisposable
    {
    public:
        FeedItem();
        void OnPropertyChanged(Platform::String^ propertyName);
         
        // ICustomPropertyProvider interface
        virtual Windows::UI::Xaml::Data::ICustomProperty^ GetCustomProperty(Platform::String^ name);
        virtual Windows::UI::Xaml::Data::ICustomProperty^ GetIndexedProperty(Platform::String^ name, Windows::UI::Xaml::Interop::TypeName typeName);
        virtual Platform::String^ GetStringRepresentation();
        virtual property Windows::UI::Xaml::Interop::TypeName Type { Windows::UI::Xaml::Interop::TypeName get(); }

    private:
        Platform::String^ _title;
        Platform::String^ _author;
        Platform::String^ _pubDate;
        Platform::String^ _content;

    public:
        property Platform::String^ Title { Platform::String^ get(); void set(Platform::String^ value); }
        property Platform::String^ Author { Platform::String^ get(); void set(Platform::String^ value); }
        property Platform::String^ PubDate { Platform::String^ get(); void set(Platform::String^ value); }
        property Platform::String^ Content { Platform::String^ get(); void set(Platform::String^ value); }

        Object^ TitleGetter(Object^ instance);
        Object^ AuthorGetter(Object^ instance);
        Object^ PubDateGetter(Object^ instance);
        Object^ ContentGetter(Object^ instance);
    };

    // CustomDataProperty: helper class for implementation of ICustomPropertyProvider interface on FeedItem
    delegate Platform::Object^ PropertyGetter(Platform::Object^ instance);
    delegate void PropertySetter(Platform::Object^ instance, Platform::Object^ value);

    ref class CustomDataProperty : public Windows::UI::Xaml::Data::ICustomProperty
    {
    private:
        Platform::String^ _typeName;
        Platform::String^ _name;
        PropertyGetter^ _propertyGetter;
        PropertySetter^ _propertySetter;

    public:
        CustomDataProperty(Platform::String^ typeName, Platform::String^ Name, PropertySetter^ PropertySetter, PropertyGetter^ PropertyGetter);
        virtual property Windows::UI::Xaml::Interop::TypeName Type { virtual Windows::UI::Xaml::Interop::TypeName get(); }
        virtual property Platform::String^ Name { virtual Platform::String^ get(); }
        virtual property bool CanRead { virtual bool get(); }
        virtual property bool CanWrite { virtual bool get(); }
        virtual Platform::Object^ GetValue(Platform::Object^ instance);
        virtual void SetValue(Object^ instance, Platform::Object^ value);
        virtual void SetIndexedValue(Platform::Object^ instance, Platform::Object^ value, Platform::Object^ index);
        virtual Platform::Object^ GetIndexedValue(Platform::Object^ instance, Platform::Object^ value);
    };
}

// C++
// FeedData.cpp
// Implementation of the FeedData and FeedItem classes
//
#include "pch.h"
#include "FeedData.h"

using namespace Platform;
using namespace Windows::Foundation;
using namespace Windows::Foundation::Collections;
using namespace Windows::UI::Xaml;
using namespace Windows::UI::Xaml::Controls;
using namespace Windows::UI::Xaml::Data;
using namespace Windows::UI::Xaml::Interop;
using namespace SimpleBlogReader;

// FeedData
FeedData::FeedData()
{
    _title = "";
 _items = ref new Vector();
}

void FeedData::OnPropertyChanged(String^ propertyName)
{
}

Vector^ FeedData::Items::get()
{
 return this->_items;
}


Object^ FeedData::TitleGetter(Object^ instance)
{
    auto object = (FeedData^)instance;
    return PropertyValue::CreateString(object->Title);
}

String^ FeedData::Title::get()
{
    return this->_title;
}

void FeedData::Title::set(String^ value)
{
    if (this->_title != value)
    {
        this->_title = value;
        this->OnPropertyChanged("Title");
    }
}

// FeedData - ICustomPropertyProvider interface
ICustomProperty^ FeedData::GetIndexedProperty(String^ name, TypeName typeName)
{
    throw ref new NotImplementedException();
}

String^ FeedData::GetStringRepresentation() 
{ 
    throw ref new NotImplementedException();
}

TypeName FeedData::Type::get()
{
 throw ref new NotImplementedException();
}

ICustomProperty^ FeedData::GetCustomProperty(String^ name)
{
    if (name == "Title")
    {
        return ref new CustomDataProperty("String", "Title", nullptr, ref new PropertyGetter(this, &FeedData::TitleGetter));
    }
    return nullptr;
}

//
// FeedItem
//
FeedItem::FeedItem()
{
    _title = "";
    _author = "";
    _pubDate = "";
    _content = "";
}

void FeedItem::OnPropertyChanged(String^ propertyName)
{
}


Object^ FeedItem::TitleGetter(Object^ instance)
{
    auto object = (FeedItem^)instance;
    return PropertyValue::CreateString(object->Title);
}

String^ FeedItem::Title::get()
{
    return this->_title;
}

void FeedItem::Title::set(String^ value)
{
    if (this->_title != value)
    {
        this->_title = value;
        this->OnPropertyChanged("Title");
    }
}

Object^ FeedItem::AuthorGetter(Object^ instance)
{
    auto object = (FeedItem^)instance;
    return PropertyValue::CreateString(object->Author);
}

String^ FeedItem::Author::get()
{
    return this->_author;
}

void FeedItem::Author::set(String^ value)
{
    if (this->_author != value)
    {
        this->_author = value;
        this->OnPropertyChanged("Author");
    }
}

Object^ FeedItem::PubDateGetter(Object^ instance)
{
    auto object = (FeedItem^)instance;
    return PropertyValue::CreateString(object->PubDate);
}

String^ FeedItem::PubDate::get()
{
    return this->_pubDate;
}

void FeedItem::PubDate::set(String^ value)
{
    if (this->_pubDate != value)
    {
        this->_pubDate = value;
        this->OnPropertyChanged("PubDate");
    }
}

Object^ FeedItem::ContentGetter(Object^ instance)
{
    auto object = (FeedItem^)instance;
    return PropertyValue::CreateString(object->Content);
}

String^ FeedItem::Content::get()
{
    return this->_content;
}

void FeedItem::Content::set(String^ value)
{
    if (this->_content != value)
    {
        this->_content = value;
        this->OnPropertyChanged("Content");
    }
}

//
// FeedItem - ICustomPropertyProvider interface
//
ICustomProperty^ FeedItem::GetIndexedProperty(String^ name, TypeName typeName)
{
    throw ref new NotImplementedException();
}

String^ FeedItem::GetStringRepresentation() 
{ 
    throw ref new NotImplementedException();
}

TypeName FeedItem::Type::get()
{
 throw ref new NotImplementedException();
}

ICustomProperty^ FeedItem::GetCustomProperty(String^ name)
{
    if (name == "Title")
    {
        return ref new CustomDataProperty("String", "Title", nullptr, ref new PropertyGetter(this, &FeedItem::TitleGetter));
    }
    else if (name == "Author")
    {
        return ref new CustomDataProperty("String", "Author", nullptr, ref new PropertyGetter(this, &FeedItem::AuthorGetter));
    }
    else if (name == "PubDate")
    {
        return ref new CustomDataProperty("String", "PubDate", nullptr, ref new PropertyGetter(this, &FeedItem::PubDateGetter));
    }
    else if (name == "Content")
    {
        return ref new CustomDataProperty("String", "Content", nullptr, ref new PropertyGetter(this, &FeedItem::ContentGetter));
    }
    return nullptr;
}

// CustomDataProperty
CustomDataProperty::CustomDataProperty(String^ typeName, String^ Name, PropertySetter^ PropertySetter, PropertyGetter^ PropertyGetter)
{
    _typeName = typeName;
    _name = Name;
    _propertyGetter = PropertyGetter;
    _propertySetter = PropertySetter;
}

TypeName CustomDataProperty::Type::get()
{
 TypeName t;
 t.Name = _typeName;
 t.Kind = TypeKind::Primitive;
 return t;
}

String^ CustomDataProperty::Name::get()
{
 return _name;
}

bool CustomDataProperty::CanRead::get()
{
 return (_propertyGetter != nullptr);
}

bool CustomDataProperty::CanWrite::get()
{
 return (_propertySetter != nullptr);
}

Object^ CustomDataProperty::GetValue(Object^ instance)
{
    return _propertyGetter(instance);
}

void CustomDataProperty::SetValue(Object^ instance, Object^ value)
{
    _propertySetter(instance, value);
}

void CustomDataProperty::SetIndexedValue(Object^ instance, Object^ value, Object^ index)
{
    throw ref new NotImplementedException;
}

Object^ CustomDataProperty::GetIndexedValue(Object^ instance, Object^ value)
{
    throw ref new NotImplementedException;
}

Retrieving the feed data

With data classes in place to hold our data, let's get back to downloading the blog feed. The Windows.Web.Syndication.SyndicationClient class retrieves a fully parsed RSS or Atom feed, so instead of tedious explanations about parsing XML, we can move on to more interesting problems. The SyndicationClient class provides only one way to retrieve a feed, and that's asynchronously. The asynchronous programming model is common in the Windows Runtime to help ensure that apps remain responsive. Fortunately, much of the complexity you might expect when using asynchronous methods has been taken care of for us.

Using await in C# and Visual Basic

Using the await keyword in C# and Visual Basic, the code for retrieving the feed asynchronously is similar to the code we would use to retrieve the feed synchronously. Let's take a look.
// C#
private async Task GetFeedAsync(string feedUriString)
{
    // using Windows.Web.Syndication;
    SyndicationClient client = new SyndicationClient();
    Uri feedUri = new Uri(feedUriString);

    try
    {
        SyndicationFeed feed = await client.RetrieveFeedAsync(feedUri);
        FeedData feedData = new FeedData();
        feedData.Title = feed.Title.Text;

        foreach (SyndicationItem item in feed.Items)
        {
            FeedItem feedItem = new FeedItem();
            feedItem.Title = item.Title.Text;
            feedItem.PubDate = item.PublishedDate.DateTime;
            feedItem.Author = item.Authors[0].Name.ToString();
            if (feed.SourceFormat == SyndicationFormat.Atom10)
            {
                feedItem.Content = item.Content.Text;
            }
            else if (feed.SourceFormat == SyndicationFormat.Rss20)
            {
                feedItem.Content = item.Summary.Text;
            }
            feedData.Items.Add(feedItem);
        }
        this.DataContext = feedData;
        ItemListView.SelectedIndex = 0;
    }
    catch (Exception ex)
    {
        // Log Error.
        TitleText.Text = ex.Message;
    }
}

' Visual Basic
Private Async Function GetFeedAsync(FeedUriString As String) As Task
    ' Imports Windows.Web.Syndication
    Dim Client As New SyndicationClient
    Dim FeedUri As New Uri(FeedUriString)

    Try
        Dim Feed As SyndicationFeed = Await Client.RetrieveFeedAsync(FeedUri)
        Dim FeedData As New FeedData
        FeedData.Title = Feed.Title.Text

        For Each Item As SyndicationItem In Feed.Items
            Dim FeedItem As New FeedItem
            FeedItem.Title = Item.Title.Text
            FeedItem.PubDate = Item.PublishedDate.DateTime
            FeedItem.Author = Item.Authors(0).Name.ToString()

            If Feed.SourceFormat = SyndicationFormat.Atom10 Then
                FeedItem.Content = Item.Content.Text
            ElseIf Feed.SourceFormat = SyndicationFormat.Rss20 Then
                FeedItem.Content = Item.Summary.Text
            End If

            FeedData.Items.Add(FeedItem)
        Next

        Me.DataContext = FeedData
        ItemListView.SelectedIndex = 0
    Catch Ex As Exception
        ' Log Error.
        TitleText.Text = Ex.Message
    End Try
End Function

The first thing to notice is that we added the async keyword to the method signature. You can use the await keyword only in a method that's defined as async.
// C# 
private async Task GetFeedAsync(string feedUriString)

' Visual Basic
Private Async Function GetFeedAsync(FeedUriString As String) As Task

Next, we call the SyndicationClient.RetrieveFeedAsync method to get the SyndicationClient that contains the RSS or Atom info that we want. The await keyword here tells the compiler to do a lot of work for us behind the scenes.
// C#
SyndicationFeed feed = await client.RetrieveFeedAsync(feedUri);

' Visual Basic
Dim Feed As SyndicationFeed = Await Client.RetrieveFeedAsync(FeedUri)

Essentially, the compiler schedules the rest of the method after this call as a callback to be executed when the call returns. It then immediately returns control to the calling thread, typically the UI thread, so that the app remains responsive. When RetrieveFeedAsync returns, the rest of the code in our method is executed. And, importantly, it's executed in the same thread context that we made the original call from (the UI thread), so we don't have to worry about using a dispatcher to update the UI in this code.
After we retrieve the SyndicationFeed with the data we want, we copy the parts we need into our FeedData and FeedItem data classes. We then set the FeedData item as the DataContext of the page so that we can bind our UI to it. We wrap the whole thing in a Try… Catch block to handle any exceptions that occur while we retrieve the feed.
We want our app to load the Developing for Windows blog automatically when it starts. For simplicity, we can call our GetFeedAsync method from the page constructor to do this. We pass in the URL for the Atom feed because it includes author data that we want to show, and the RSS feed doesn't.
// C#
public MainPage()
{
    InitializeComponent();
    GetFeedAsync("http://windowsteamblog.com/windows/b/developers/atom.aspx");
}

' Visual Basic
Public Sub New()
    InitializeComponent()
    GetFeedAsync("http://windowsteamblog.com/windows/b/developers/atom.aspx")
End Sub

// C++
MainPage::MainPage()
{
    InitializeComponent();
    GetFeedAsync("http://windowsteamblog.com/windows/b/developers/atom.aspx");
}

Retrieving the feed data in C++

In C++, the feed is also retrieved asynchronously. But instead of using await, we use an AsyncOperationWithProgressCompletedHandler delegate named Feed_Done. This delegate contains the feed processing code that is executed after the feed is returned.
// C++
// Decalaration in MainPage.xaml.h
void GetFeedAsync(Platform::String^ feedUriString);
void Feed_Done(Windows::Foundation::IAsyncOperationWithProgress
                ^);

// Implementation in MainPage.xaml.cpp
void SimpleBlogReader::MainPage::GetFeedAsync(Platform::String^ feedUriString)
{ 
 client = ref new SyndicationClient;
 auto feedOperation = client->RetrieveFeedAsync(ref new Uri(feedUriString));

 feedOperation->Completed = ref new AsyncOperationWithProgressCompletedHandler
                                      (this, &MainPage::Feed_Done);
 feedOperation->Start();
}

void MainPage::Feed_Done(IAsyncOperationWithProgress^ op)
{

 if(op->Status == AsyncStatus::Completed) {
  auto feed = op->GetResults();

  FeedData^ feedData = ref new FeedData();
  feedData -> Title = feed->Title->Text;

  // Used to format PubDate
  auto dtf = ref new Windows::Globalization::DateTimeFormatting::DateTimeFormatter
                       (YearFormat::Full, MonthFormat::Numeric, DayFormat::Default, DayOfWeekFormat::None);
  for(int i=0; i< feed->Items->Size; i++) {
   FeedItem^ feedItem = ref new FeedItem();
   feedItem->Title = feed->Items->GetAt(i)->Title->Text;
   feedItem->PubDate = dtf->Format(feed->Items->GetAt(i)->PublishedDate);
   feedItem->Author = feed->Items->GetAt(i)->Authors->GetAt(0)->Name;
   if (feed->SourceFormat == SyndicationFormat::Atom10)
            {
                feedItem->Content = feed->Items->GetAt(i)->Content->Text;
            }
            else if (feed->SourceFormat == SyndicationFormat::Rss20)
            {
                feedItem->Content = feed->Items->GetAt(i)->Summary->Text;
            }
   feedData->Items->Append(feedItem);
  }

  // Bind the collection to the list
  this->DataContext = feedData;
  this->ItemListView->ItemsSource = feedData->Items;
  this->ItemListView->SelectedIndex = 0;
 }
}

Defining the app layout in XAML

In this section, you will learn:
  • what panels you can use to define a layout in XAML
  • how to define rows and columns in a Grid
  • how to use a StackPanel.
The app layout specifies the sizing and positioning of objects in your app. To position visual objects, you must put them in a Panel control or other container object. The XAML layout system provides various Panel controls, such as Grid, Canvas, and StackPanel, that serve as containers in which you position and arrange the controls.
The XAML layout system supports both absolute layout and dynamic layout. In an absolute layout, you position controls using explicit x-y coordinates (for example, by using a Canvas). In a dynamic layout, the layout container and the controls can be automatically sized and repositioned as the app resizes (for example, by using a StackPanel or a Grid). In practice, you typically define the layout of your app by combining absolute and dynamic methods, and by embedding panels within other panels.
A typical layout that is useful for a blog reader app looks like this, with the title at the top, a list of posts on the left, and the content of the selected post on the right.
An example of layout.
By default, the blank app template includes a Grid named LayoutRoot. To achieve our layout, we divide the Grid into two rows. The top row holds the blog title. In the second row, we embed another Grid, divide it into two columns, and add some more layout containers to display the blog content.
    
        
            
            
        

        

        
        
            
                
                
            

            
            

            
            
                
                    
                    
                
            
        
     


Let's look at what this XAML does in more detail. To define rows in a Grid, you add RowDefinition objects to the Grid.Rows collection. You can set properties on the RowDefinition to specify the appearance of the row. You add columns in the same way, using ColumnDefinition objects and the Grid.Columns collection.
In XAML, the row definitions looks like this:

  
  



The Height="140" property setting on the first row definition (row 0) sets the top row to an absolute height of 100 pixels. This height doesn't change regardless of the size of the row contents or the application. The Height="*" setting on the second row definition (row 1) tells the bottom row to take up whatever space is left after row 0 has sized itself. This is often called star sizing. We also use star sizing in the column definitions of the second Grid. The width settings of Width="2*" and Width="3*" tell the Grid to divide itself into 5 equal parts. Two parts are used for the first column, and three parts are used for the second column.
To position an element within the Grid, you set the Grid.Row and Grid.Column attached properties on the element. Remember that the row and column numbering is zero-based. The default value of these properties is 0, so if you don't set anything, the element will go into the first row and the first column.
The element embeds a Grid within the bottom row of the LayoutRoot Grid. This Grid is divided into two columns.
The element adds a ListView to the left hand column of the bottom Grid. The element adds another Grid to the right hand column of the bottom Grid. We divide this Grid into two rows. The setting Height="Auto" tells the top row to make itself as tall as it needs to be to fit its content. The bottom row uses whatever space is left.
The last part of our UI that needs a layout panel is the list of blog posts. In this list, we need to arrange the title, author, and date as shown here.
An example of a StackPanel. You typically use a StackPanel when you want to automatically arrange consecutive elements in a small subsection of the UI on your page. The StackPanel is a simple layout panel that arranges its child elements into a single line that can be oriented horizontally or vertically. You can use the StackPanel.Orientation property to specify the direction of the child elements. The default value for the Orientation property is Orientation.Vertical. We use a StackPanel to arrange the items in our list of blog posts. We'll see it in use in the section, Formatting data with data templates. The XAML for the StackPanel looks like this.

    
    
    


Adding controls and content

In this section, you will learn how to:
  • add controls to an app
  • add text to an app
  • add graphics to and app
  • add images to an app.
Layout panels are important, but they're not very interesting without content to put in them. You create the UI for your app by adding controls such as buttons, lists, text, graphics, and images. The elements you use depend on what your app does. Let's take a look at some of the controls we can use in our Metro style app. Then we add some controls to our blog reader to display the data we retrieved.

Buttons and selection controls

Users typically interact with an app though buttons and selection controls. Some common controls of this type are Button, HyperlinkButton, RadioButton, CheckBox, ListBox, and Slider.
Here's how to add a Button using XAML.

Text

You can use TextBlock andRichTextBlock to display text, and TextBox to input text. PasswordBox is a special masked text box that you can use to input passwords.
Here's how to add a TextBlock and a TextBox using XAML.




Data and web views

You can use several different kinds of controls display data from collections or a web page. The ListView, GridView, and FlipView controls display collections of data. You can use the WebView control to render HTML content.

Graphics

You can add geometric shapes to your app's UI. The Shape classes are Line, Ellipse, Rectangle, Polygon, Polyline, and Path. To create shapes, define a Geometry, and then assign Brushes to render the outline and the fill. For a Shape to be rendered to the screen, you must set a Brush to the Stroke property of the Shape to render its outline, or set a Brush to the Fill property to render its fill. The different types of brushes are SolidColorBrush, LinearGradientBrush, ImageBrush, and WebViewBrush.
This example creates an Ellipse shape with a Width of 300, a Height of 200, and a Tan SolidColorBrush as its Fill.


Images

To display an image, you can either use an Image control, or use an ImageBrush to paint an image onto another control.
The example here shows how to display an image by using the Image object. In this example, the Source property specifies the location of the image that you want to display. You can set the Source by specifying an absolute URL (for example, http://contoso.com/myPicture.jpg) or by specifying the URL of a file relative to your app files.


With the ImageBrush object you can use an image to paint an area of another object. This example shows how to use an ImageBrush as the Fill of an Ellipse. For an ImageBrush, the ImageSource property specifies the location of the image to display.

   
     
   



Note  When you use an ImageBrush as the Fill for an Ellipse, you need a different XAML syntax than we used in the previous Ellipse example. In the previous Ellipse example, you just set the Fill property to Tan using Attribute syntax. You didn't need to specify anything about the type of Brush because the XAML parser knows how to convert the string, Tan, to the appropriate SolidColorBrush. But to specify the properties of the ImageBrush you must use an expanded XAML syntax called PropertyElement syntax. With this syntax you can set the ImageSource property on the ImageBrush.

Adding controls to the blog reader

Looking at the sketch of our blog reader UI, it's clear that we need to display one-line text (the blog and post titles), multiline-text (the post content), and a list of blog posts. We add TextBlock controls to display the titles, and a ListView control to display the list of blog posts. At first glance, it seems that we might use a multi-line TextBlock or RichTextBlock to display the post content. But, when we dig deeper, we see that the string that contains the post content is not plain text, but a string of HTML. We don't want to display a bunch of HTML tags, which is what will happen if we put the string in a TextBlock, so we use a WebView control to display the HTML.
With controls added, the XAML for our UI now looks like this.
    
        
            
            
        

        
        

        
        
            
                
                
            

            
            
                
                    
                        
                            
                            
                            
                        
                    
                
            

            
            
            
                
                    
                    
                
                
                
            
        
    

Displaying data

In this section, you will learn how to:
  • bind data to UI
  • format data with templates.

Binding data to UI

In the Hello World app that we started with, we updated the text in the UI by setting the Text property of the TextBlock in this button click event handler.
// C#
private void HelloButton_Click(object sender, RoutedEventArgs e)
{
    DisplayText.Text = "Hello World";
}

' Visual Basic
Private Sub HelloButton_Click(ByVal sender As Object, ByVal e As RoutedEventArgs)
    DisplayText.Text = "Hello World"
End Sub

// C++
void HelloWorld::MainPage::HelloButton_Click(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e)
{
    DisplayText->Text = "Hello World";

}

Sometimes setting a Text property in code like this works well. But to display data, you typically use data binding to connect a data source to the UI. When you establish a binding and the data source changes, the UI elements that are bound to the data source can reflect changes automatically. Similarly, changes made by the user in a UI element can be reflected in the data source. For example, if the user edits the value in a TextBox, the binding engine automatically updates the underlying data source to reflect that change.
In the blog reader app, we show the blog title by binding the Text property of the title TextBlock to the Title property of a source object.



The title of the selected blog post is shown in the same way.


But wait! If both TextBlocks have exactly the same binding, how do they show different titles? The answer is in the DataContext that each TextBlock is bound to. The DataContext property lets you set the default binding for an entire UI element, including all of its child elements. Sometimes, you set the DataContext property for an entire page, and at other times, you set it for individual elements on the page. The DataContext setting at each XAML level overrides any settings at a higher level. Also, you can override any DataContext setting in effect for an individual binding by setting its Source property.
In the blog reader app, we set the DataContext for the whole page in the code behind. Remember that after retrieving the data feed, we set the DataContext with this line of code.
// C#
this.DataContext = feedData;

' Visual Basic
Me.DataContext = FeedData

// C++
this->DataContext = feedData;

The context of the first TextBlock, then, is the FeedData object, so it shows the FeedData.Title property.
How does the second TextBlock show the title of the selected blog post? The second TextBlock is within a StackPanel, as we see here.

      
      ...


Notice that the DataContext of the StackPanel is bound to the SelectedItem property of the ListView. So again the binding engine works for us behind the scenes. Whenever the selection changes in the ListView, the DataContext of the StackPanel is updated automatically to be the selected post. The DataContext of the StackPanel overrides the DataContext of the page, so the second TextBlock displays the FeedItem.Title property of the selected blog post.
Each binding has a Mode property that specifies how and when the data is updated. OneTime binding means that the value is set on the target only when the binding is first created, but never updated after that. OneWay binding means that the target is updated if the source changes. TwoWay binding means that both the target and the source are updated if either one changes. If you use OneWay or TwoWay bindings, for the binding to be notified of changes to the source object, you must implement the INotifyPropertyChanged interface.
For more info about data binding, see QuickStart: Data binding to controls.

Formatting data with a data template

Showing the data we want in the list view is slightly more complex than just setting the binding. We have the ListView bound to the Items property of the FeedData object, so the correct data is there. But if we run the app like this, the ListView doesn't know what to show, so it just calls ToString on the object it's bound to. That gives us a list of "SimpleBlogReader.FeedItem" strings like this one. Clearly, this is not what we want to show.
A bound list with no template.We can make it a little better by setting the DisplayMemberPath property on the ListView. This tells the list view to call ToString on the specified property of the bound object, instead of on the object itself. If we set DisplayMemberPath=Title, the ListView shows a list of blog post titles.



Here we see that this is closer to what we want to show.
A bound list showing the title.But what we really want is to show the title, author, and published date for each post in the list. For that, we define a template that tells the ListView exactly how we want the data displayed. The controls for viewing collections of data items are derived from the ItemsControl class. These controls have an ItemTemplate property that we can assign a DataTemplate to. The DataTemplate defines how our data looks.
Here's the XAML for the ListView using a DataTemplate defined inline instead of DisplayMemberPath.

    
        
            
                
                
                
            
        
    


Defining the bit of UI inside the DataTemplate is just like defining any other UI. We use a StackPanel to stack three TextBlocks on top of each other. We then bind the Text property of TextBlocks to the Title, Author, and PubDate properties. The default DataContext for these bindings is the object displayed in the ListView, which is a FeedItem.
Here's what the list looks like when we use a template to define it's appearance.
A bound list using a data template.

Formatting data with a value converter

Note   The C++ version of the sample code uses a DateTimeFormatter to format the date, so the date converter in this section is shown in C# and Visual Basic only.
In ItemListView's DataTemplate, we bind the PubDate property, which is a DateTime, to a TextBlock.Text property. The binding engine automatically convertsPubDatefrom a DateTime to a string for us. But the automatic conversion shows both the date and the time, and we want to show only the time. To fix this, we can create our own value converter that converts a DateTime to a string, and in it we can format the string however we want to.
To create a value converter, we create a class that implements the IValueConverter interface and then implement the Convert and ConvertBack methods. Converters can change data from one type to another, translate data based on cultural info, or modify other aspects of the presentation. Here, we create a date converter that converts the date value passed in and formats it so that it shows only the day, the month, and the year.
// C#
public class DateConverter : Windows.UI.Xaml.Data.IValueConverter
{
    public object Convert(object value, string targetType, object parameter, string culture)
    {
        DateTime dt = (DateTime)value;
        // Date "7/27/2011 9:30:59 AM" returns "7/27/2011"
        return dt.ToString("d");
    }

    public object ConvertBack(object value, string targetType, object parameter, string culture)
    {
        string strValue = value as string;
        DateTime resultDateTime;
        if (DateTime.TryParse(strValue, out resultDateTime))
        {
            return resultDateTime;
        }
        return DependencyProperty.UnsetValue;
    }
}

' Visual Basic
Public Class DateConverter
    Implements Windows.UI.Xaml.Data.IValueConverter

    Public Function Convert(ByVal value As Object, ByVal targetType As String, ByVal parameter As Object, ByVal culture As String) _
        As Object Implements Windows.UI.Xaml.Data.IValueConverter.Convert
        Dim dt As DateTime = DirectCast(value, DateTime)
        ' Date "7/27/2011 9:30:59 AM" returns "7/27/2011"
        Return dt.ToString("d")
    End Function

    Public Function ConvertBack(ByVal value As Object, ByVal targetType As String, ByVal parameter As Object, ByVal culture As String) _
        As Object Implements Windows.UI.Xaml.Data.IValueConverter.ConvertBack
        Dim StrValue As String = DirectCast(value, String)
        Dim Result As Date
        If DateTime.TryParse(StrValue, Result) Then
            Return Result
        End If
        Return DependencyProperty.UnsetValue
    End Function
End Class

Before we can use the DateConverter class, we must declare an instance of it in our XAML. First, we add an XML namespace mapping at the top of MainPage.xaml. This gives us access to classes in our project using the declared namespace. Here, we map the SimpleBlogReader project to the namespace "local".
xmlns:local="using:SimpleBlogReader"
We then declare an instance of DateConverter with the key dateConverter as a resource of the page.
    
        
    
Now we can use the DateConverter in our binding. Here's the updated binding from ItemListView's DataTemplate.


With this XAML, the binding engine uses our custom DateConverter to change a DateTime to a string. The string that it returns is formatted the way we want, with only the day, month, and year.
Tip  The Convert and ConvertBack methods also let you pass in a parameter so that you can use the same instance of the converter with different options. For example, you can write a formatting converter that produces different formats of data based on the input parameter that you use. You can use the ConverterParameter of the Binding class to pass a parameter as an argument into the Convert and ConvertBack methods. The sample project for the Enhancing your first Windows Metro style app with C# or Visual Basic topic uses a modified DateConverter that demonstrates this.

Displaying HTML in a WebView

To show a blog post in our app the final step is to get the post data to show in the WebView control. The WebView control gives us a way to host HTML data within our app. But if we look at its Source property, we see that it takes a Uri for the web page to display. Our HTML data is just a string of HTML. It doesn't have a Uri that we can bind to the Source property. Luckily, there is a NavigateToString method that we can pass our string of HTML to.
To make this work, we handle the ListView's SelectionChanged event. Here's the XAML for the ListView with the SelectionChanged event added.

    ...

In the event handler, we cast the Selected Item to a FeedItem and get the string of HTML from the Content property. We then pass the string to the NavigateToString method.
// C#
private void ItemListView_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
    FeedItem feedItem = (sender as ListView).SelectedItem as FeedItem;
    if (feedItem != null)
    {
        // Navigate the WebView to the blog post content HTML string.
        ContentView.NavigateToString(feedItem.Content);
    }
} 

' Visual Basic
Private Sub ItemListView_SelectionChanged(sender As Object, e As SelectionChangedEventArgs)
    Dim FeedItem As FeedItem = TryCast(TryCast(sender, ListView).SelectedItem, FeedItem)
    If FeedItem IsNot Nothing Then
        ' Navigate the WebView to the blog post content HTML string.
        ContentView.NavigateToString(FeedItem.Content)
    End If
End Sub

// C++
// Declaration in MainPage.xaml.h
void ItemListView_SelectionChanged(Platform::Object^ sender, Windows::UI::Xaml::Controls::SelectionChangedEventArgs^ e);

// Implementation in MainPage.xaml.cpp
void SimpleBlogReader::MainPage::ItemListView_SelectionChanged
       (Platform::Object^ sender, Windows::UI::Xaml::Controls::SelectionChangedEventArgs^ e)
{
    FeedItem^ feedItem = safe_cast(ItemListView->SelectedItem);
    if (feedItem != nullptr)
    {
        // Navigate the WebView to the blog post content HTML string.
        ContentView->NavigateToString(feedItem->Content);
    }
}

Here's what the finished app looks like when we run it.
Finished blog reader app.

What's next?

Congratulations! You've built your first Metro style app. What to do now? Here are some suggestions:
About the author...
Jim Walker has been at Microsoft since 1997, and has been writing about XAML since 2007 as a Programming Writer in the Developer Division and in Windows.

Could not find a part of the path ... bin\roslyn\csc.exe

I am trying to run an ASP.NET MVC (model-view-controller) project retrieved from TFS (Team Foundation Server) source control. I have added a...