• Win8的RSS阅读器


       学习Win8开发也有一段时间,最初是看传智播客老杨的Win8视频教程,才对Win8有了一定开发基础,然后参考着微软官方的API及源码学习。在这里与大家分享我做的一个小小Demo供大家参考。

      本Demo只是现实了Rss的基本阅读功能,当然还可以扩展很多的功能,让它变得更完美些。在这里先与大家分享这基本的现实功能,我也一会继续优化。。。

      在项目中我觉得最核心的知识点:

      1、使用Win8提供的类库下载并解析Xml文件。

      2、格式化文本展示新闻内容。

      先上效果图 ,有图有真相。然后再分享实现过程,在结尾处会提供参考源代码。

       下面,我们一起实现步骤:

      1、创建Win8商店应用程序(不要说不会啊~~  )。

      2、随便找个RSS订阅的地方,了解了解结构,大家从贴图上也看出来了,我这里用的就是博客园的最新新闻,提供个地址:http://feed.cnblogs.com/news/rss

      3、有了第2步的基础之后,我们来创建一个类:FeedItem.cs ,属性字段看着办就行~~,开发Win8程序的实体类要记得实现一个这个接口(INotifyPropertyChanged),至于是为什么,直接不解释,不会的去看视频。贴上源代码:

    View Code
     /// <summary>
        /// 新闻实体类
        /// </summary>
        public class FeedItem : INotifyPropertyChanged
        {
    
            private int _id;
            public int Id
            {
                get { return _id; }
                set
                {
                    _id = value;
                    OnPropertyChanged("Id");
                }
            }
    
            private string _title;
            public string Title
            {
                get { return _title; }
                set
                {
                    _title = value;
                    OnPropertyChanged("Title");
                }
            }
    
            private string _content;
            public string Content
            {
                get { return _content; }
                set
                {
                    _content = value;
                    OnPropertyChanged("Content");
                }
            }
            private DateTime _pubDate;
            public DateTime PubDate
            {
    
                get { return _pubDate; }
                set
                {
                    _pubDate = value;
                    OnPropertyChanged("PubDate");
                }
            }
    
            private string _link;
            public string Link
            {
                get { return _link; }
                set { _link = value; OnPropertyChanged("Link"); }
            }
            protected void OnPropertyChanged(string propertyName)
            {
                if (this.PropertyChanged != null)
                {
                    this.PropertyChanged(this, new System.ComponentModel.PropertyChangedEventArgs(propertyName));
                }
            }
    
            public event PropertyChangedEventHandler PropertyChanged;
        }

      4、添加一个新的空白页:Index.xmal 这个页面是重点,用到了GridView来展示集合中的内容。

      XMAL代码:

    View Code
     <Grid Background="Gray">
            <Grid.RowDefinitions>
                <RowDefinition Height="auto"></RowDefinition>
                <RowDefinition></RowDefinition>
            </Grid.RowDefinitions>
            <StackPanel Margin="20">
                <TextBlock Text="博客园 - 最新新闻" Style="{StaticResource HeaderTextStyle}"></TextBlock>
                <GridView Grid.Row="1" Margin="0 30 0 0" x:Name="ItemGridView" 
                ItemTemplate="{StaticResource StoreFrontTileTemplate}"
                ItemContainerStyle="{StaticResource StoreFrontTileStyle}"
                ItemsPanel="{StaticResource StoreFrontGridItemsPanelTemplate}"
                VerticalAlignment="Top"
                BorderThickness="1" ScrollViewer.VerticalScrollBarVisibility="Auto"
                ScrollViewer.HorizontalScrollBarVisibility="Auto" SelectionMode="Single"
                   SelectionChanged="ItemGridView_SelectionChanged_1"
                      />
                <ProgressBar Name="pro1" Grid.Row="1" Background="White" IsIndeterminate="True" />
            </StackPanel>
        </Grid>

      后台代码:

      /// <summary>
        /// 可用于自身或导航至 Frame 内部的空白页。
        /// </summary>
        public sealed partial class Index : Page
        {
            //新闻集合
            ObservableCollection<FeedItem> feedData = null;
    
            public Index()
            {
                InitializeComponent();
            }
    
            /// <summary>
            /// 在此页将要在 Frame 中显示时进行调用。
            /// </summary>
            /// <param name="e">描述如何访问此页的事件数据。Parameter
            /// 属性通常用于配置页。</param>
            protected override void OnNavigatedTo(NavigationEventArgs e)
            {
                //加载
                InitItem();
                this.ItemGridView.ItemsSource = feedData;
    
            }
            /// <summary>
            /// 加载XML
            /// </summary>
            public async void InitItem()
            {
                if (feedData != null)
                {
                    return;
                }
                SyndicationClient client = new SyndicationClient();
                Uri feedUri = new Uri("http://feed.cnblogs.com/news/rss");
                feedData = new ObservableCollection<FeedItem>();
                try
                {
                    SyndicationFeed feed = await client.RetrieveFeedAsync(feedUri);
                    pro1.Visibility = Windows.UI.Xaml.Visibility.Collapsed;
    
                    foreach (SyndicationItem item in feed.Items)
                    {
                        FeedItem feedItem = new FeedItem();
                        string id = item.Id.ToString();
                        Regex reg = new Regex(@".(\d+).");
                        Match m = reg.Match(id);
                        string s = m.Groups[1].ToString();
                        feedItem.Id = Convert.ToInt32(s);
                        feedItem.Link = item.Id.ToString();
                        feedItem.Title = item.Title.Text;
                        feedItem.PubDate = item.PublishedDate.DateTime;
                        if (feed.SourceFormat == SyndicationFormat.Atom10)
                        {
                            feedItem.Content = item.Content.Text;
                        }
                        else if (feed.SourceFormat == SyndicationFormat.Rss20)
                        {
                            feedItem.Content = item.Summary.Text;
                        }
                        feedData.Add(feedItem);
                    }
    
                }
                catch (Exception)
                {
    
                }
            }
    
            private void ItemGridView_SelectionChanged_1(object sender, SelectionChangedEventArgs e)
            {
                FeedItem feedItem = e.AddedItems[0] as FeedItem;
                //页面跳转
                Frame.Navigate(typeof(Details), feedItem);
            }
    
        }

      哈哈,完成这四步就可以展示列表信息了。当然要注意的几点:

        (1)、xmal中的GridView几个模版样式我是写在app.xmal中,你必须要在app.xmal中写上模版样式,要不然肯定会报错滴。因为我也不知道要用啥颜色效果,所以整个的页面风格我全部设置为灰色了。自己改改喜欢的样式呗。

      app.xmal中的代码:

    View Code
     <Application.Resources>
            <ResourceDictionary>
                <ResourceDictionary.MergedDictionaries>
    
                    <!-- 
                        用于定义平台外观的共同方面的样式
                        Visual Studio 项目和项模板所必需的
                     -->
                    
                    <ResourceDictionary Source="Common/StandardStyles.xaml"/>
                </ResourceDictionary.MergedDictionaries>
                <Style x:Key="ItemTitleStyle" TargetType="TextBlock">
                    <Setter Property="FontFamily" Value="Segoe UI Light"/>
                    <Setter Property="FontSize" Value="34"/>
                </Style>
    
                <Style x:Key="ItemSubtitleStyle" TargetType="TextBlock">
                    <Setter Property="FontFamily" Value="Segoe UI Light"/>
                    <Setter Property="FontSize" Value="24"/>
                </Style>
    
                <DataTemplate x:Key="StoreFrontTileTemplate">
                    <Grid HorizontalAlignment="Left" Background="DarkGray" >
                        <StackPanel Orientation="Horizontal" Margin="5,5,0,0" >
                            <StackPanel Margin="0,0,0,0" Orientation="Vertical">
                                <TextBlock TextWrapping="Wrap" Foreground="{StaticResource ApplicationForegroundThemeBrush}" Style="{StaticResource ItemTitleStyle}" Width="400" Height="200" VerticalAlignment="Center" Text="{Binding Title}" HorizontalAlignment="Left" FontFamily="Segoe UI" />
                                <TextBlock TextWrapping="Wrap" Foreground="{StaticResource ApplicationForegroundThemeBrush}" Style="{StaticResource ItemSubtitleStyle}" Width="400" Height="100" VerticalAlignment="Center" Text="{Binding PubDate}" HorizontalAlignment="Left"/>
                            </StackPanel>
                        </StackPanel>
                    </Grid>
                </DataTemplate>
    
                <Style x:Key="StoreFrontTileStyle"  TargetType="GridViewItem">
                    <Setter Property="FontFamily" Value="Segoe UI" />
                    <Setter Property="Height" Value="300" />
                    <Setter Property="Width" Value="400" />
                    <Setter Property="Padding" Value="0" />
                    <Setter Property="Margin" Value="0,0,8,8" />
                    <Setter Property="HorizontalContentAlignment" Value="Left" />
                    <Setter Property="VerticalContentAlignment" Value="Top" />
                    <Setter Property="BorderThickness" Value="0"/>
                    <Setter Property="TabNavigation" Value="Local" />
                </Style>
    
                <Style x:Key="StoreFrontLVTileStyle"  TargetType="ListViewItem">
                    <Setter Property="FontFamily" Value="Segoe UI" />
                    <Setter Property="Height" Value="80" />
                    <Setter Property="Width" Value="292" />
                    <Setter Property="Padding" Value="0" />
                    <Setter Property="Margin" Value="0,0,8,8" />
                    <Setter Property="HorizontalContentAlignment" Value="Left" />
                    <Setter Property="VerticalContentAlignment" Value="Top" />
                    <Setter Property="BorderThickness" Value="0"/>
                    <Setter Property="TabNavigation" Value="Local" />
                </Style>
    
                <ItemsPanelTemplate x:Key="StoreFrontGridItemsPanelTemplate">
                    <WrapGrid MaximumRowsOrColumns="2" VerticalChildrenAlignment="Center"
                          HorizontalChildrenAlignment="Left"/>
                </ItemsPanelTemplate>
    
            </ResourceDictionary>
        </Application.Resources>

      

        (2)、得使用ObservableCollection集合类型,比List之类的要更先进此。

        (3)、InitItem方法 加载并解析xml方法。要记得引用几个命名空间。

        (4)、ItemGridView_SelectionChanged_1这个当点击之后要执行的事件,因为我们还没有创建详情页,但是你又想看看效果,可以先这里面的代码注释一下,跑跑看,如果能跑起来,那就说明离成功不远了。先休息一会儿,坐久了可不好,顺便喝个水。

      当然如果跑起来有错误,不要着急,看错误在哪,有问题解决就行。。。

      过了N久之后。。。。

      5、好,我们接着来创建一个新的页面:Details.xaml

      先直接贴上代码:

    View Code
    <Grid Background="Gray">
            <Grid Margin="20">
                <Grid.RowDefinitions>
                    <RowDefinition Height="auto"></RowDefinition>
                    <RowDefinition></RowDefinition>
                </Grid.RowDefinitions>
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="auto"></ColumnDefinition>
                    <ColumnDefinition></ColumnDefinition>
                </Grid.ColumnDefinitions>
    
                <Button Grid.Row="0" Grid.Column="0" Content="返回" Style="{StaticResource BackButtonStyle}" Click="Button_Click_1" HorizontalAlignment="Left" Margin="44,35,0,0" VerticalAlignment="Top"/>
                <TextBlock Name="txtTitle" HorizontalAlignment="Center" VerticalAlignment="Bottom" Style="{StaticResource HeaderTextStyle}" Grid.Row="0" Grid.Column="1"></TextBlock>
                <ScrollViewer Grid.Row="1" Grid.ColumnSpan="2" HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Hidden">
                    <StackPanel Name="stPanel" Orientation="Horizontal"></StackPanel>
                </ScrollViewer>
            </Grid>
        </Grid>

      后台代码:

    /// <summary>
        /// 可用于自身或导航至 Frame 内部的空白页。
        /// </summary>
        public sealed partial class Details : Page
        {
            public Details()
            {
                this.InitializeComponent();
            }
    
            /// <summary>
            /// 在此页将要在 Frame 中显示时进行调用。
            /// </summary>
            /// <param name="e">描述如何访问此页的事件数据。Parameter
            /// 属性通常用于配置页。</param>
            protected override void OnNavigatedTo(NavigationEventArgs e)
            {
                if (e.NavigationMode == NavigationMode.New)
                {
                    FeedItem f = e.Parameter as FeedItem;
                    txtTitle.Text = f.Title;
                    //对新闻内容字符串处理   
                    string content = HtmlUtilities.ConvertToText(f.Content + " --" + f.PubDate).Replace("本文链接", "");
                    ShowTxt(content);
                }
            }
    
            private void Button_Click_1(object sender, RoutedEventArgs e)
            {
                //返回
                Frame.GoBack();
            }
    
            const double CT_WIDTH = 400d; //文本块的宽度
            const double CT_HEIGHT = 600d; //文本块的高度
            const double CT_MARGIN = 20d; //文本块的边距
    
            /// <summary>
            /// 显示新闻 
            /// </summary>
            /// <param name="msg"></param>
            private void ShowTxt(string msg)
            {
                stPanel.Children.Clear();
    
                // 去掉特殊的换行符
                msg = msg.Replace(" ", "").Replace("\n", "").Replace("\r", "\n").Replace("\t", "");
                msg = Regex.Replace(msg, @"\r\n{1,}", "\r\n");
                msg = Regex.Replace(msg, @"\n{1,}", "\n");
                msg = Regex.Replace(msg, @"^\n{1,}", "");
               
                // 为了支持文本分块,使用RichTextBlock
                RichTextBlock tbContent = new RichTextBlock();
                tbContent.Width = CT_WIDTH;
                tbContent.Height = CT_HEIGHT;
                tbContent.TextWrapping = TextWrapping.Wrap;
                tbContent.Margin = new Thickness(CT_MARGIN);
    
                Paragraph ph = new Paragraph();
                ph.TextIndent = 33;
    
                Run txtRun = new Run();
                txtRun.Text = msg;
                ph.Inlines.Add(txtRun);
    
                tbContent.Blocks.Add(ph);
                tbContent.FontSize = 24;
    
                stPanel.Children.Add(tbContent);
                // 更新一下状态,方便获取是否有溢出的文本
                tbContent.UpdateLayout();
                bool isflow = tbContent.HasOverflowContent;
                // 因为除了第一个文本块是RichTextBlock,
                // 后面的都是RichTextBlockOverflow一个一个接起来的
                // 所以我们需要两个变量
                RichTextBlockOverflow oldFlow = null, newFlow = null;
                if (isflow)
                {
                    oldFlow = new RichTextBlockOverflow();
                    oldFlow.Width = CT_WIDTH;
                    oldFlow.Height = CT_HEIGHT;
                    oldFlow.Margin = new Thickness(CT_MARGIN);
                    tbContent.OverflowContentTarget = oldFlow;
                    stPanel.Children.Add(oldFlow);
                    oldFlow.UpdateLayout();
                    // 继续判断是否还有溢出
                    isflow = oldFlow.HasOverflowContent;
                }
                while (isflow)
                {
                    newFlow = new RichTextBlockOverflow();
                    newFlow.Height = CT_HEIGHT;
                    newFlow.Width = CT_WIDTH;
                    newFlow.Margin = new Thickness(CT_MARGIN);
    
                    oldFlow.OverflowContentTarget = newFlow;
                    stPanel.Children.Add(newFlow);
                    newFlow.UpdateLayout();
                    // 继续判断是否还有溢出的文本
                    isflow = newFlow.HasOverflowContent;
                    // 当第一个变量填充了文本后,
                    // 把第一个变量的引用指向当前RichTextBlockOverflow
                    // 确保OverflowContentTarget属性可以前后相接
                    oldFlow = newFlow;
                }
            }
        }

      关于这个展示文本的方法:ShowTxt(),算个重点,  用RichTextBlock控件来展示新闻内容。当然这里面的代码不了解的,先贴上去看看效果,哈哈,我也不太了解,只是写了很多次,把这个格式背下来了,反正以后要用到类似的地方,直接把这个代码贴上去就可以。

      F5 跑起来~~~~

      先按照步骤一步步做下来,如果还是有错呢,可以下载源代码,对比一下。

      终于给写完了,如果你看到了这里,真是谢谢啊!

      此项目参考"传智播客.net培训Windows 8开发视频教程"  、 Microsoft官方提供API帮助。 

       源码下载

  • 相关阅读:
    使用VisualVM检测
    《自控力》读书笔记
    【转】Oracle索引的类型
    【转】Oracle索引HINT的使用
    【转】Oracle 执行计划(Explain Plan) 说明
    Oracle分区
    【转】Oracle索引失效问题
    【转】《从入门到精通云服务器》第七讲—负载均衡和CDN技术
    【转】《从入门到精通云服务器》第七讲—IAAS、PAAS、SAAS
    【转】《从入门到精通云服务器》第六讲—OpenStack基础
  • 原文地址:https://www.cnblogs.com/xdpxyxy/p/2787842.html
Copyright © 2020-2023  润新知