Чтение каналов RSS и Atom

107

В качестве примера рассмотрим приложение для чтения синдицируемых каналов, которое называется SyndicationReader и имеет пользовательский интерфейс, разработанный с помощью WPF. На рисунке ниже показано, как выглядит интерфейс этого приложения:

Интерфейс приложения SyndicationReader

Для использования API-интерфейса Syndication в приложение добавлена ссылка на сборку System.ServiceModel.dll. Исполняющему роль обработчика событий методу OnGetFeed() назначается событие Click кнопки с текстом "Получить канал".

Код, необходимый приложению для чтения, выглядит действительно очень просто. Сначала производится считывание XML-содержимого из RSS-канала в класс XmlReader пространства имен System.Xml. Далее с помощью метода ReadFrom( )объект XmlReader передается классу Rss20FeedFormatter. После этого для осуществления привязки данных свойство Feed, возвращающее SyndicationFeed, присваивается свойству DataContext объекта Window, а свойство Feed.Items, возвращающее IEnumerable<SyndicationItem>, присваивается свойству DataContext контейнера DockPanel:

private void OnGetFeed(object sender, RoutedEventArgs e)
{
        try
        {
                using (XmlReader reader = XmlReader.Create(textUrl.Text))
                {
                    var formatter = new Rss20FeedFormatter();
                    formatter.ReadFrom(reader);
                    this.DataContext = formatter.Feed;
                    this.feedContent.DataContext = formatter.Feed.Items;
                }
        }
        catch (WebException ex)
        {
                MessageBox.Show(ex.Message, "Syndication Reader");
        }
}

Код XAML, необходимый для определения пользовательского интерфейса, показан ниже. Здесь свойство Title класса Window сначала привязывается к свойству Title.Text объекта SyndicationFeed для обеспечения отображения заголовка канала. Далее определяется элемент управления StackPanel по имени heading, в котором содержится один элемент управления Label, привязываемый к Title.Text, и один элемент управления Label, привязываемый к Description.Text. Поскольку эти элементы управления Label содержатся внутри элемента управления DockPanel по имени feedContent, а этот feedContent привязывается к свойству Feed.Items, они будут отвечать за отображение заголовка и описания элемента, выбранного в текущий момент.

Список элементов отображается в элементе управления ListBox, в котором для привязки элементов управления Label к Title применяется ItemTemplate. В элементе DockPanel по имени content содержится элемент Frame, в котором свойство Source связывается с первой ссылкой элемента. Благодаря этому элемент управления Frame использует элемент управления типа веб-браузера для отображения содержимого из этой ссылки:

<Window x:Class="SyndicationSample.SyndicationReaderWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="{Binding Path=Title.Text}" Height="300" Width="450">

    <DockPanel x:Name="feedContent">
        <Grid  DockPanel.Dock="Top">
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="50" />
                <ColumnDefinition Width="*" />
                <ColumnDefinition Width="140" />
            </Grid.ColumnDefinitions>
            <Label Grid.Column="0" Margin="5">URL:</Label>
            <TextBox Grid.Column="1" x:Name="textUrl" MinWidth="150" Margin="5"/>
            <Button Grid.Column="2" Margin="5" MinWidth="80"
                    Click="OnGetFeed">Получить канал</Button>
        </Grid>
        <StackPanel Orientation="Vertical" DockPanel.Dock="Top" Background="LightGreen" x:Name="heading">
            <Label Content="{Binding Path=Title.Text}" FontSize="16" />
            <Label Content="{Binding Path=Description.Text}" />
        </StackPanel>
        <ListBox MinWidth="120"  DockPanel.Dock="Left" ItemsSource="{Binding}"
                 IsSynchronizedWithCurrentItem="True" HorizontalContentAlignment="Stretch">
            <ListBox.ItemTemplate>
                <DataTemplate>
                    <Border Background="#555">
                        <Label Content="{Binding Title.Text}" Foreground="#DDD" />
                    </Border>
                </DataTemplate>
            </ListBox.ItemTemplate>
        </ListBox>
        <DockPanel x:Name="content">
            <Label DockPanel.Dock="Top" Content="{Binding Description.Text}" />
            <Frame Source="{Binding Path=Links[0].Uri}" />
        </DockPanel>

    </DockPanel>
</Window>
Пройди тесты
Лучший чат для C# программистов