全文涉及到的是C#和XAML

如果这两门语言并非你喜欢的语言,那可以关闭本网页了

  • 本文介绍的是什么?
  1. 一个火车站点信息查询软件
  • 本文涉及到的WPF基本知识
  1. Task
  2. async await
  3. WebClient
  4. 数据绑定

  这基本知识其他blog会有这更详细的讲解,本文将不会详细介绍这些内容

  • 实现的基本原理
  1. 通过webclient 获取 指定网页静态资源
  2. 分析静态资源,并提取火车的站点信息
  • 编译环境和平台
  1. VS2012
  2. .NET4.5

先通过几张截图看看本文介绍的应用是什么

界面做的不是太好,但基本功能都已实现

界面的实现

  • 界面中包含了一个静态资源 DataTemplate UITraninID
    • 作为显示所有火车ID的List的ItemTemplat
  • UIMainGrid 用于显示某火车的详细站点信息
    • 包含一个Textblock和一个DataGrid,分别显示ID和详细站点
 <Window x:Class="Train.MainWindow"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         Title="MainWindow" Height="450" Width="525" WindowStartupLocation="CenterScreen">

     <Window.Resources>
         <DataTemplate x:Key="UITrainID">
             <TextBlock Text="{Binding ID}" Foreground="Black" FontSize="17" Width="70" TextAlignment="Center" />
         </DataTemplate>
     </Window.Resources>
     <Grid>
         <Grid.RowDefinitions>
             <RowDefinition Height="60"/>
             <RowDefinition Height="*"/>
         </Grid.RowDefinitions>
         <Grid Background="Black">
             <Grid.ColumnDefinitions>
                 <ColumnDefinition Width="100"/>
                 <ColumnDefinition Width="*"/>
                 <ColumnDefinition Width="*"/>
                 <ColumnDefinition Width="140"/>
             </Grid.ColumnDefinitions>
             <TextBlock Text="欢迎" Foreground="White" FontSize="20" HorizontalAlignment="Center" VerticalAlignment="Center"/>
             <Button x:Name="UIOpenFile" BorderThickness="0" Foreground="White" Background="Transparent" Content="打开文件" Grid.Column="1" FontSize="20" Click="UIOpenFile_Click" />
             <Button x:Name="UISave" BorderThickness="0" Foreground="White" Background="Transparent" Content="保存" Grid.Column="2" FontSize="20" Click="UISave_Click" />
             <Button x:Name="UIAbout" BorderThickness="0" Foreground="White" Background="Transparent" Content="关于本应用" Grid.Column="3" FontSize="20" Click="UIAbout_Click" />

         </Grid>
         <Grid Grid.Row="1">
             <Grid.ColumnDefinitions>
                 <ColumnDefinition Width="100"/>
                 <ColumnDefinition Width="*"/>
             </Grid.ColumnDefinitions>
             <Grid>
                 <Grid.RowDefinitions>
                     <RowDefinition Height="50"/>
                     <RowDefinition Height="*"/>
                 </Grid.RowDefinitions>
                 <Grid Background="LightSkyBlue">
                     <TextBlock Text="列车ID" FontSize="19" HorizontalAlignment="Center" VerticalAlignment="Center" />
                 </Grid>
                 <ListView
                     x:Name="UIlist"
                     ItemTemplate="{StaticResource ResourceKey=UITrainID}"
                     BorderThickness="0"
                     Grid.Row="1" SelectionChanged="UIlist_SelectionChanged"/>
             </Grid>
             <Grid x:Name="UIMainGrid" Grid.Column="1">
                 <Border BorderThickness="1,0,0,0" BorderBrush="Black" />
                 <Grid Margin="30,15,30,50">
                     <Grid.RowDefinitions>
                         <RowDefinition  Height="50"/>
                         <RowDefinition  Height="*"/>
                     </Grid.RowDefinitions>
                     <Grid Background="LightGreen">
                         <TextBlock Text="{Binding ID}" FontSize="20" HorizontalAlignment="Left" VerticalAlignment="Center" Margin="20,0,0,0" />
                     </Grid>
                     <Grid Background="AliceBlue" Grid.Row="1">
                         <DataGrid IsReadOnly="True" ItemsSource="{Binding All_station}" HorizontalAlignment="Center" VerticalAlignment="Center"  />
                     </Grid>
                 </Grid>
             </Grid>
             <Grid Grid.Column="1">
                 <ProgressBar x:Name="UIPro" Value="0" Background="Salmon" Height="40" Margin="86,0,0,0" VerticalAlignment="Bottom"/>
                 <TextBlock x:Name="UItext" TextWrapping="Wrap" Text="100" VerticalAlignment="Top" FontSize="17" HorizontalAlignment="Left" Margin="100,33,0,0" />
                 <TextBlock Foreground="Green" HorizontalAlignment="Left" Margin="25,0,0,10" TextWrapping="Wrap" Text="进度" VerticalAlignment="Bottom" FontSize="17" FontWeight="Bold"/>
             </Grid>
         </Grid>
     </Grid>
 </Window>

下面设计详细

这是下文将会用到的几个静态资源

private static string send = "</div>";//站点信息结束标示符
        private static string sbegin = "result-data";//站点信息开始标示符
        private static string SiteUrl = "http://piao.huoche.com/checi/{0}/";//URL模板

        private static string surl;

        public static List<TrainInfo> AllTrain = new List<TrainInfo>();    //所有信息

1.获取指定网页静态资源

         public static List<station> GetWebData()
         {
             WebClient myWebClient = new WebClient();

             //skip certificate error
             ServicePointManager.ServerCertificateValidationCallback = delegate { return true; };
             try
             {
                 // stream get  html_sourcefile
                 Stream myStream = myWebClient.OpenRead(surl);
                 StreamReader sr = new StreamReader(myStream, System.Text.Encoding.GetEncoding("utf-8"));

                 //get data
                 var result = PickInfo(sr.ReadToEnd());

                 //close stream
                 myStream.Close();

                 return result;
             }
             catch { return null; }
         }

通过OpenRead方法获取 指定url 的数据流

实体化StreamReader类,并调用ReadToEnd()方法,获取静态string资源

并调静态资源分析函数

返回指定网页的所有站点的一个 List<station>

2.分析网页源码

        public static List<station> PickInfo(string s)
         {
             List<station> allstation = new List<station>();

            int index_begin = s.IndexOf(sbegin);
         int index_end = s.IndexOf(send, index_begin);

             )
                 .Split('<', '>');
             , value = ;

             ; i < stemp.Length; i++)
             {
                 stemp[i] = stemp[i].Trim();

                 try
                 {
                     value = int.Parse(stemp[i]);
                 }
                 catch
                 {
                     continue;
                 }

                 if (value != n) continue;

                 //while (stemp[i].Contains("td") || !ISChinese(stemp[i])) i++;
                 i+=;
                 station astation = new station
                 {
                     Name = stemp[i],
                     Index = n
                 };
                 i+=;

                 astation.ArriveTime = stemp[i];
                 i+=;
                 astation.LeaveTime = stemp[i];
                 i+=;
                 astation.TimeSum = stemp[i];
                 i += ;
                 allstation.Add(astation);
                 n++;
             }
             return allstation;
         }

简单的字符串处理,代码写的并不是太好。。

3.我已经有了一个保存所有车次ID的文本,如何获取并显示所有火车信息

读取文本信息,对于每一ID,实体化一个 TrainInfo类,并加入到AllTrainList里面

TrainInfo 包含两个属性

  1. string ID
  2. list<station> all_station

通过调用异步方法GETDATA()

[网络不稳定因素可能导致调用该方法时占用大量时间,所以采用异步实现]

根据ID,生成一个URL连接,并new 一个task->GetWebData ,去获取该页面的数据

         public static async Task<List<station>> GetData(string id)
         {
             Task<List<station>> task = new Task<List<station>>(GetWebData);
             surl = string.Format(SiteUrl,id);
             task.Start();
             return await task;

         }

4.UI显示

UI主要有两个控件用于显示数据,分别是

  1. ListView,显示查询的所有火车的ID
  2. DataGrid,显示某个ID的所有站点信息

为什么不是每一个TrainInfo都对应一个DataGrid

在大量查询时,如果每个TrainInfo都对应一个DataGrid,将会占用大量内存

还有一个progressbar 用于显示当前数据的获取状态

具体实现如下

        private async void UIOpenFile_Click(object sender, RoutedEventArgs e)
        {

            if (!Global.fileopen()) return;
            //showpro();
            IdList.Clear();
            UIPro.Maximum = Global.AllTrain.Count;
            UIPro.Value = ;
            foreach (var x in Global.AllTrain)
            {
                UItext.Text = string.Format(sGetInfo, x.ID) + "\n" + swait;
                x.All_station = await Global.GetData(x.ID);
                IdList.Add(new UITrainTextBlock { ID = x.ID });
                UIPro.Value++;
            }

            UItext.Text = "";
            //showdata();

        }

源工程下载:

http://files.cnblogs.com/lightz/Train.zip

【WPF】【火车站点信息查询】的更多相关文章

  1. java实现根据起点终点和日期查询去哪儿网的火车车次和火车站点信息

    本文章为原创文章,转载请注明,欢迎评论和改正. 一,分析 之前所用的直接通过HTML中的元素值来爬取一些网页上的数据,但是一些比较敏感的数据,很多正规网站都是通过json数据存储,这些数据通过HTML ...

  2. 火车车次查询-余票查询--Api接口

    1.来自12306的火车车次数据 使用12306网站的接口,查询余票.此接口采集自 这里. 全国火车站代号字典,下载 . 火车票余票查询 http://dynamic.12306.cn/otsquer ...

  3. jQuery Mobile应用之火车票查询

    效果图: 在CMD中输入如下代码 corsproxy (前提是有node.js环境,并先安装corsproxy) html: <!DOCTYPE html> <html> &l ...

  4. 我的Android进阶之旅------>关于调用Webservice查询火车票时刻表的几个接口介绍

    今天发现一个可以提供火车票时刻表查询的WebService,先记录下来以后如果写一个火车票时刻表查询的Android App的话就用的着.首先该WebService的的名字是TrainTimeWebS ...

  5. 最实用的IT类网站及工具大集合

    1.聚合数据 大家在开发过程中,可能会用到各种各样的数据,想找一些接口来提供一些数据.比如天气预报查询,火车时刻表查询,彩票查询,身份证查询等等.有了这个接口,直接调用即可.各种各样的API接口满足你 ...

  6. 干货!IT小伙伴们实用的网站及工具大集合!持续更新!

    1.Git 还在担心自己辛辛苦苦写的代码被误删了吗?还在担心自己改错了代码不能挽回吗?还在苦恼于多人开发合作找不到一个好的工具吗?那么用Git就对 了,Git是一个开源的分布式版本控制系统,用以有效. ...

  7. Android和Linux应用综合对比分析

    原文地址:http://www.cnblogs.com/beer/p/3325242.html 免责声明: 当时写完这篇调查报告,给同事看了后,他觉得蛮喜欢,然后想把这篇文章修改一下,然后往期刊上发表 ...

  8. 最实用的IT类网站及工具大集合[转]

    1.聚合数据 大家在开发过程中,可能会用到各种各样的数据,想找一些接口来提供一些数据.比如天气预报查询,火车时刻表查询,彩票查询,身份证查询等等.有了这个接口,直接调用即可.各种各样的API接口满足你 ...

  9. IOS网络开发(三)

    1 飞机航班查询软件 1.1 问题 NSURLConnection是IOS提供的用于处理Http协议的网络请求的类,可以实现同步请求也可以实现异步请求,本案例使用NSURLConnection类实现一 ...

随机推荐

  1. linux下的共享库(动态库)和静态库

    1.什么是库在windows平台和linux平台下都大量存在着库.本质上来说库是一种可执行代码的二进制形式,可以被操作系统载入内存执行.由于windows和linux的本质不同,因此二者库的二进制是不 ...

  2. NDK(21)JNI的5大正确性缺陷及优化技巧(注意是正确性缺陷)

    转自 : http://www.ibm.com/developerworks/cn/java/j-jni/index.html JNI 编程缺陷可以分为两类: 性能:代码能执行所设计的功能,但运行缓慢 ...

  3. SGU 441 Set Division(矩阵快速幂)

    题目链接:http://acm.sgu.ru/status.php 题意:将n个有区别的球放到m个无区别的盒子里,盒子不能为空.不同的方案数. 思路:设f[i][j]表示将前i个球放到j个盒子里,那么 ...

  4. Android 中Activity生命周期分析:Android中横竖屏切换时的生命周期过程

    最近在面试Android,今天出了一个这样的题目,即如题: 我当时以为生命周期是这样的: onCreate --> onStart -- ---> onResume ---> onP ...

  5. bzoj2085

    首先看到k的范围就该知道这题不是倍增就是矩乘 首先肯定要求出任意一对串(a,b) a的后缀与b的前缀相同的最长长度是多少 考虑到kmp求出的失配指针是一个串最长后缀和前缀相等的长度 这里多个串我们只要 ...

  6. UVa 10780 (质因数分解) Again Prime? No Time.

    求mk整除n!,求k的最大值. 现将m分解质因数,比如对于素数p1分解出来的指数为k1,那么n!中能分解出多少个p1出来呢? 考虑10!中2的个数c:1~10中有10/2个数是2的倍数,c += 5: ...

  7. [转]Jquery Ajax用法

    原文地址:http://www.php100.com/html/program/jquery/2013/0905/6004.html jQuery学习之jQuery Ajax用法详解 来源:   时间 ...

  8. Java [Leetcode 205]Isomorphic Strings

    题目描述: Given two strings s and t, determine if they are isomorphic. Two strings are isomorphic if the ...

  9. Java [Leetcode 232]Implement Queue using Stacks

    题目描述: Implement the following operations of a queue using stacks. push(x) -- Push element x to the b ...

  10. 编写爬虫(spider)的预备知识:用java发送HTTP请求

    使用原生API来发送http请求,而不是使用apache的库,原因在于这个第三方库变化实在太快了,每个版本都有不小的变化.对于程序员来说,使用它反而会有很多麻烦,比如自己曾经写过的代码将无法复用. 原 ...