Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

Picasaweb Album Viewer using XMLDataProvider and WPF

0.00/5 (No votes)
21 Aug 2007 1  
Picasaweb Album Viewer using XMLDataProvider and WPF

Introduction

This application shows how easy it is to create Google's Picasa Web album viewer using WPF and XMLDataProvider.

Background

As there are a number of applications that do the same using code behind, I have tried to use XAML wherever possible (moreover, there are no WPF sample applications I know that use Picasa Web APIs, so Picasa Web was my default choice). I could have extended the application but I think this should be enough to give you a head start. I am not following best practices as my main aim is to show the easiness and the concept.

Using the Code

The application is a window based application and uses a dock panel. The dock panel has two panels i.e. left and right. The left panel contains a listbox that enumerates the various albums from my picasaweb folder. The right panel displays all the pictures from the selected album.

<Window x:Class="PictureViewer.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="clr-namespace:PictureViewer" 
    Title="PictureViewer" SizeToContent="WidthAndHeight"
    >
  <DockPanel>
    
    <ScrollViewer ScrollViewer.VerticalScrollBarVisibility="Auto" 
        ScrollViewer.HorizontalScrollBarVisibility="Auto">
      <ListBox DockPanel.Dock="Left" SelectionChanged="OnSelctionChanged" 
            DataContext="{StaticResource Picasa}"  
            ItemsSource="{Binding XPath=default:feed/default:entry/default:title}">
      </ListBox>
    </ScrollViewer>
    
    <ListBox x:Name="MyListBox" ...>
     ...
    </ListBox>
  </DockPanel>
</Window> 

To read the albums from Picasa Web album, the xmldataprovider should understand and use the same XML namespace as Picasa Web. To do this, add the following XML namespace tags as a dockpanel resource:

  <XmlNamespaceMappingCollection x:Key="mapping">
    <XmlNamespaceMapping Uri="http://www.w3.org/2005/Atom" Prefix="default"/>
    <XmlNamespaceMapping Uri="http://schemas.google.com/photos/2007" Prefix="gphoto"/>
  </XmlNamespaceMappingCollection>

Next, we need to add an xmldataprovider as a resource so we could fetch albums from my picasaweb folder. Here we set the source to my picasaweb album folder. (You may bind and replace my user-id with yours but well, I am a narcissist so I am not going to show you how:

<XmlDataProvider x:Key="Picasa" XmlNamespaceManager="{StaticResource mapping}" 
    Source="http://picasaweb.google.com/data/feed/api/user/rohits79?kind=album">
      </XmlDataProvider>

I have added the above two as a resource as we shall reuse and bind as a StaticResource later in the project.

Now, when the application loads, it would get the list of all the albums from my picasaweb folder (as xmldataprovider is part of the resource). Next we need that the listbox in the left panel should list all the albums. For this, parse the XML node list from the xmldataprovider and read only the album's title; the populated album's title list should be set as ItemsSource property of listbox. The efficient way to do the above is by using XPath as below.

<ScrollViewer ScrollViewer.VerticalScrollBarVisibility="Auto" 
    ScrollViewer.HorizontalScrollBarVisibility="Auto">
      <ListBox DockPanel.Dock="Left" DataContext="{StaticResource Picasa}"  
            ItemsSource="{Binding XPath=default:feed/default:entry/default:title}">
      </ListBox>
    </ScrollViewer>

Our next goal is that when the user clicks on the left listbox we should show all the pictures from the selected album folder in the right listbox/panel. To do this, add an event handler in the left listbox.

 <ListBox DockPanel.Dock="Left" SelectionChanged="OnSelctionChanged" 
    DataContext="{StaticResource Picasa}"  
    ItemsSource="{Binding XPath=default:feed/default:entry/default:title}">

The event handler shall get all pictures from the selected album folder using XMLDataprovider which is also set as the datacontext of the right listbox as shown below:

public void OnSelctionChanged(Object source, RoutedEventArgs args)
        {
            ListBox lb = args.Source as ListBox;
            string simplestr;
            XmlDataProvider provider = MyListBox.DataContext as XmlDataProvider;
            if (provider != null)
            {
                simplestr = lb.SelectedValue.ToString().Replace(" ", "");
                simplestr = simplestr.Replace(",", "");
                provider.Source = new Uri
                    (@http://picasaweb.google.com/data/feed/api/user/rohits79/album/ 
                    + simplestr  + "?kind=photo");
            }
        }

Once again, parse the binary picture content using XPath as we did for the left listbox.

<ListBox x:Name="MyListBox" 
    ItemsSource="{Binding XPath=/default:feed/default:entry/default:content}" 
    ScrollViewer.HorizontalScrollBarVisibility="Disabled" BorderBrush="White">

Update the datatemplate of the listbox so that the listbox items are rendered as images instead of as the default listbox items.

   <ListBox x:Name="MyListBox" 
        ItemsSource="{Binding XPath=/default:feed/default:entry/default:content}" 
        ScrollViewer.HorizontalScrollBarVisibility="Disabled" BorderBrush="White">
      <ListBox.DataContext>
        <XmlDataProvider XmlNamespaceManager="{StaticResource mapping}">
        </XmlDataProvider>
      </ListBox.DataContext>
      <ListBox.ItemTemplate>
        <DataTemplate>
          <Image Source="{Binding XPath=@src}" Width="300"></Image>
        </DataTemplate>
      </ListBox.ItemTemplate>
      <ListBox.ItemsPanel>
        <ItemsPanelTemplate>
          <WrapPanel/>
        </ItemsPanelTemplate>
      </ListBox.ItemsPanel>
    </ListBox>

The following is the full XAML code where the right listbox items are wrapped using WrapPanel.

<Window x:Class="PictureViewer.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x=http://schemas.microsoft.com/winfx/2006/xaml 
    xmlns:local="clr-namespace:PictureViewer" Title="PictureViewer" 
    SizeToContent="WidthAndHeight"><DockPanel><DockPanel.Resources >
    <XmlNamespaceMappingCollection x:Key="mapping">
    <XmlNamespaceMapping Uri="http://www.w3.org/2005/Atom" Prefix="default"/>
    <XmlNamespaceMapping Uri=http://schemas.google.com/photos/2007 
    Prefix="gphoto"/>
</XmlNamespaceMappingCollection><XmlDataProvider x:Key="Picasa" 
    XmlNamespaceManager="{StaticResource mapping}" 
    Source="http://picasaweb.google.com/data/feed/api/user/rohits79?kind=album">
</XmlDataProvider>
</DockPanel.Resources>
<ScrollViewer ScrollViewer.VerticalScrollBarVisibility="Auto" 
    ScrollViewer.HorizontalScrollBarVisibility="Auto">
<ListBox DockPanel.Dock="Left" SelectionChanged="OnSelctionChanged" 
    DataContext="{StaticResource Picasa}"  
    ItemsSource="{Binding XPath=default:feed/default:entry/default:title}">
      </ListBox>
    </ScrollViewer>
<ListBox x:Name="MyListBox" 
    ItemsSource="{Binding XPath=/default:feed/default:entry/default:content}" 
    ScrollViewer.HorizontalScrollBarVisibility="Disabled" BorderBrush="White">
      <ListBox.DataContext>
        <XmlDataProvider XmlNamespaceManager="{StaticResource mapping}">
        </XmlDataProvider>
      </ListBox.DataContext>
      <ListBox.ItemTemplate>
        <DataTemplate>
          <Image Source="{Binding XPath=@src}" Width="300"></Image>
        </DataTemplate>
      </ListBox.ItemTemplate>
      <ListBox.ItemsPanel>
        <ItemsPanelTemplate>
          <WrapPanel/>
        </ItemsPanelTemplate>
      </ListBox.ItemsPanel>
    </ListBox>
  </DockPanel>
</Window> 

At the end, here is how the final application will look:

Screenshot - picasaweb.jpg

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here