Leafing Through News Articles on Your Tablet

I thought it would be neat to simulate a real newspaper experience in my news reader app running on a tablet. I decided to use the FlipView control to display the text of the article. The control allows users to use sliding gestures to move forwards and backwards. Slide left to move forward on the article list, and slide right to move backwards.

To make the experience more user-friendly, I thought that I would want to scroll the text all the way to the beginning every time the view changes from one article to the next. To achieve this, I found that I had to derive from the basic FlipView to gain access to the VisualTree of the NewsArticle. The ActionSelectedItemView method below can be called from the outside, providing a News Article, the method, in turn will call the provided delegate, passing the root of the Visual Tree as a parameter.

class CustomFlipView :FlipView
{
    public void ActionSelectedItemView(Action<DependencyObject> action)
    {
        if (SelectedItem == null)
            return;

        var element = this.ItemContainerGenerator.ContainerFromItem(SelectedItem);
        if (element != null)
        {
            action(element);
        }
    }
}

And this is how I use it: whenever item changes, my delegate gets called back with a visual root of the current SelectedItem, so I find the ScrollViewer and I scroll it to the top.

public sealed partial class LandscapeView : UserControl
{
   public LandscapeView()
   {
      this.InitializeComponent();
      contentViewHolder.SelectionChanged += contentViewHolder_SelectionChanged;
   }

   private void contentViewHolder_SelectionChanged(object sender, SelectionChangedEventArgs e)
   {
      var fv = sender as CustomFlipView;
      fv.ActionSelectedItemView(dp =>
      {
         var view = dp.GetFirstDescendantOfType();
         if (view != null)
         {
            view.ScrollToVerticalOffset(0);
         }
      });
  }
}

Now, what about the flipping experience? Well, to do this I bound my FlipView ItemSource to the list of articles in the Selected RSS feed. I bound the SelectedItem property of the FlipView to the SelectedItem property of the Selected RSS Feed.

The Template used hold all items is a VirtualizingStackPanel with a Horizontal Orientation. Horizontal, because I want to flip from right to left, not from top to bottom. For a sample, go here: http://msdn.microsoft.com/en-us/library/windows/apps/xaml/hh781233.aspx. The VirtualizingStackPanel will create and cache up to 3 visuals at any given moment – one for the currently visible item, one for the previous and one for the next.


<local:CustomFlipView ItemsSource="{Binding SelectedFeed.FeedItems}" x:Name="contentViewHolder"  
  SelectedItem="{Binding SelectedFeed.SelectedItem, Mode=TwoWay}">
    <FlipView.ItemsPanel>
        <ItemsPanelTemplate>
<VirtualizingStackPanel Orientation="Horizontal"/>
        </ItemsPanelTemplate>
    </FlipView.ItemsPanel>
    <FlipView.ItemTemplate>
        <DataTemplate>
<ScrollViewer Style="{StaticResource VerticalScrollViewerStyle}" 
          HorizontalScrollBarVisibility="Disabled" 
          VerticalScrollBarVisibility="Auto"
          FlowDirection="{Binding Path=Content.FlowDirection, RelativeSource={RelativeSource Self}}"
          x:Name="contentView" Content="{Binding FullText, Converter={StaticResource newsToXaml}}"/>
        </DataTemplate>
    </FlipView.ItemTemplate>
</local:CustomFlipView>

The converter will load the Visual, a properly formatted article text into the ScrollViewer, so every time users swipe from left to right, they navigate from article to article.

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s