案例(二)(13)
4.省市选择程序
(1)数据全部来源于数据库,ComboBox的显示值:Item.Add的参数是Object类型,也就是可以放 任意数据类型的数据,可以放置DisplayMember属性设定显示的属性,通过SelectedItem属性取得选择的条目对应的对象。(取出来的是 Object,如何转换为对应的类型)
(2)创建一个ProvinceItem类,将数据填充到这个对象中。
第一步:创建一个窗体ProvCityWindow。拖动三个ListBox,命名为lbProv,lbCity, lbCountry
第二步:创建一个Area.cs类代码如下:
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace ExecuteReader执行查询 { class Area { public int AreaId { get; set; } public string AreaName { get; set; } public int AreaPid { get; set; } } }
第三步:窗体ProvCityWindow添加Loaded事件,代码如下:
private void Window_Loaded(object sender, RoutedEventArgs e) { DataTable table = SqlHelper.ExecuteDataTable("Select * from AreaFull where AreaPid =0"); List<Area> listPro = new List<Area>(); foreach (DataRow datarow in table.Rows) { Area area = new Area(); area.AreaId = (int)datarow["AreaId"]; area.AreaName=(string)datarow["AreaName"]; // area.AreaPid =(int)datarow["AreaPid"]; listPro.Add(area); } lbProv.ItemsSource = listPro; }
第四步:为lbProv创建lbProv_SelectionChanged事件,代码如下:
private void lbProv_SelectionChanged(object sender, SelectionChangedEventArgs e) {//获得选中省的Area对象 Area areaProv = (Area)lbProv.SelectedItem; //获得所以的AreaPid等于选中省的AreaId的值,就是选中省的下属市 DataTable dtCity = SqlHelper.ExecuteDataTable("select * from AreaFull where AreaPid=@pid", new SqlParameter("@pid", areaProv.AreaId)); List<Area> listCity= new List<Area>(); foreach (DataRow row in dtCity.Rows) { Area areaCity = new Area(); areaCity.AreaId = (int)row["AreaId"]; areaCity.AreaName = (string)row["AreaName"]; // areaCity.AreaPid = (int)row["AreaPid"]; listCity.Add(areaCity); } lbCity.ItemsSource = listCity; }
同理添加lbCity_SelectionChanged事件,代码如下:
private void lbCity_SelectionChanged(object sender, SelectionChangedEventArgs e) { //获得选中市的Area对象 Area areaCity = (Area)lbCity.SelectedItem; //获得所以的AreaPid等于选中市的AreaId的值,就是选中省的下属市 DataTable dtCountry = SqlHelper.ExecuteDataTable("select * from AreaFull where AreaPid=@pid", new SqlParameter("@pid", areaCity.AreaId)); List<Area> listCountry = new List<Area>(); foreach (DataRow row in dtCountry.Rows) { Area areaCountry = new Area(); areaCountry.AreaId = (int)row["AreaId"]; areaCountry.AreaName = (string)row["AreaName"]; // areaCity.AreaPid = (int)row["AreaPid"]; listCountry.Add(areaCountry); } lbCountry.ItemsSource = listCountry;
第五步:修改ProvCiytWiindow.XAML中的代码,添加DisplayMemberPath如下:
<Grid Width="407"> <StackPanel Orientation="Horizontal"> <ListBox DisplayMemberPath="AreaName" Height="250" Margin="3" HorizontalAlignment="Left" Name="lbProv" VerticalAlignment="Top" Width="101" SelectionChanged="lbProv_SelectionChanged" /> <ListBox DisplayMemberPath="AreaName" Height="250" Margin="3" HorizontalAlignment="Left" Name="lbCity" VerticalAlignment="Top" Width="101" SelectionChanged="lbCity_SelectionChanged" /> <ListBox DisplayMemberPath="AreaName" Height="250" Margin="3" HorizontalAlignment="Left" Name="lbCountry" VerticalAlignment="Top" Width="101" /> </StackPanel> </Grid>
注意修改App.XAMl中的StartupUri="ProvCiytWiindow.xaml"。运行即可。(需要的数据库在文件中下载,名称为《省市数据库》)
5.手机号码归属地查询
设计数据库表,写程序把文本文件中的数据导入到数据库;开发搜索功能。到58.com上找手机号测试。
第一步:设计数据库表如下:T_TelNum
第二步:创建一个窗体名为TelSearchWindow.xaml,并拖一个按钮用于导入数据,名为btnImport,修改App.xaml中的StartupUri="TelSearchWindow.xaml"
第三步为按钮btnImport创建Click事件,代码如下:
private void btnImport_Click(object sender, RoutedEventArgs e) { OpenFileDialog ofd = new OpenFileDialog(); ofd.Filter = "文本文件|*.txt"; if (ofd.ShowDialog() == false) { return; } //查看文件的编码格式,可以在文件->另存为->编码中查看,若是ANSI使用参数DEFAULT编码即可, //若是UTF-8不使用参数,或是指定UTF-8即可 //IEnumerable<string> lines= File.ReadLines("ofd.FileName" ,Encoding.Default); //也可以使用如下的方式将其变成string数组。 string[] lines = File.ReadLines(ofd.FileName, Encoding.Default).ToArray(); //foreach(string line in lines) //{遍历的是每一行,因在文件中的第一行是表头无法遍历,所以使用for循环 //} for (int i = 1; i < lines.Count(); i++) { //string line = lines.ElementAt(i);当使用IEnumerable<string>时候使用此方式 string line = lines[i]; //注意文件里是按制表符来分割的,不是字符串 string[] strs =line.Split('\t');//‘\t’为制表符 string startTelNum = strs[0]; string telArea = strs[1]; telArea = telArea.Trim('"');//去掉两边的双引号:"北京市" string telType = strs[2]; telType = telType.Trim('"');//去掉两边的双引号:"联通" string telZone = strs[3]; telZone = telZone.Trim('"');//去掉两边的双引号:"010" //在C#中字符串前加@是可以多行声明的 SqlHelper.ExecuteNonQuery(@"insert into T_TelNum(StartTelNum,TelArea,TelType,TelZone) values(@startTelNum,@TelArea,@TelType,@TelZone)", new SqlParameter("@startTelNum", startTelNum), new SqlParameter("@TelArea", telArea),new SqlParameter("@TelType", telType), new SqlParameter("@TelZone", telZone)); } MessageBox.Show("导入成功"); }
补充内容:数据库文本文件的内容格式为:
需要再次进行修改的内容有:
1.插入失败后的数据回滚,
2.插入过程显示进度条,完成搜索功能。
3.每次插入和插入后都需要打开和再次关闭,效率慢,可以导入前打开连接,插入过程不关闭连接,都插入后再关闭。实现过程大致如下:
using (SqlConnection conn = new SqlConnection(connStr)) { conn.Open(); for (int i = 1; i < lines.Count(); i++) { string line = lines[i]; //注意文件里是按照制表符分割的,不是字符串 string[] strs = line.Split('\t');//vs里 '\t'为制表符 string startTelNum = strs[0]; string city = strs[1]; city = city.Trim('"');//去掉两边的双引号:"北京市" string telType = strs[2]; telType = telType.Trim('"'); using (SqlCommand cmd = conn.CreateCommand()) { cmd.CommandText = } } }