黑马程序员技术交流社区

标题: 关于ADO.NET的一些小疑问 [打印本页]

作者: Always.    时间: 2013-9-24 11:55
标题: 关于ADO.NET的一些小疑问
本帖最后由 Always. 于 2013-9-24 18:40 编辑

省市选择器:
思路大概是这样子的(一步一步往下走):1.从数据库里读取数据
2.将读取到的每一条数据添加到cmb省中
3.得到选择省的Id
4当选择省的Id和数据库中city表的Id匹配时,读取市的名字
代码如下:
  1. using System;
  2. using System.Collections.Generic;
  3. using System.ComponentModel;
  4. using System.Data;
  5. using System.Drawing;
  6. using System.Linq;
  7. using System.Text;
  8. using System.Windows.Forms;
  9. using System.Data.SqlClient;
  10. using System.Configuration;
  11. namespace 省市选择器
  12. {
  13.     public partial class Form1 : Form
  14.     {
  15.         public Form1()
  16.         {
  17.             InitializeComponent();
  18.             string dataDir = AppDomain.CurrentDomain.BaseDirectory;
  19.             if (dataDir.EndsWith(@"\bin\Debug\")
  20.                 || dataDir.EndsWith(@"\bin\Release\"))
  21.             {
  22.                 dataDir = System.IO.Directory.GetParent(dataDir).Parent.Parent.FullName;
  23.                 AppDomain.CurrentDomain.SetData("DataDirectory", dataDir);
  24.             }

  25.             string cnonStr = ConfigurationManager.ConnectionStrings["connStr"].ConnectionString;             // 配置文件
  26.             using (SqlConnection conn = new SqlConnection(cnonStr))
  27.             {
  28.                 conn.Open();
  29.                 using (SqlCommand cmd = conn.CreateCommand())
  30.                 {
  31.                     cmd.CommandText = "select * from promary";
  32.                     using (SqlDataReader reader = cmd.ExecuteReader())
  33.                     {
  34.                         while (reader.Read())
  35.                         {
  36.                             provinceItem item = new provinceItem();                                      //产生一个Item对象
  37.                             item.Id = reader.GetInt32(reader.GetOrdinal("proID"));                   //得到省的Id
  38.                             item.Name = reader.GetString(reader.GetOrdinal("proName"));            //得到省的名字   
  39.                             cmb省.Items.Add(item); //向省中添加Item的内容
  40.                         }
  41.                     }
  42.                 }

  43.             }
  44.         }
  45.         private void cmb省_SelectedIndexChanged(object sender, EventArgs e)
  46.         {
  47.             cmb市.Items.Clear();                        //清除市里边的旧数据
  48.             provinceItem item = (provinceItem)cmb省.SelectedItem;                     //这个item里边包含两个信息,一个是Id,一个是省的名字
  49.             int proID = item.Id;                   //得到选择省的Id
  50.             string cnonStr = ConfigurationManager.ConnectionStrings["connStr"].ConnectionString;
  51.             using (SqlConnection conn = new SqlConnection(cnonStr))
  52.             {
  53.                 conn.Open();
  54.                 using (SqlCommand cmd = conn.CreateCommand())
  55.                 {
  56.                     cmd.CommandText = "select * from city where proID=@proID";
  57.                     cmd.Parameters.Add(new SqlParameter("proID", proID));                       //后边的这个proID是选择省的ID

  58.                     using (SqlDataReader reader = cmd.ExecuteReader())
  59.                     {
  60.                         while (reader.Read())  //对于每一条取出cityname
  61.                         {
  62.                             string cityname = reader.GetString(reader.GetOrdinal("cityName"));
  63.                             cmb市.Items.Add(cityname);
  64.                         }
  65. }
  66.                 }
  67.             }
  68.   }     
  69.     }
  70.     class provinceItem
  71.     {
  72.         public string Name { get; set; }
  73.         public int Id { get; set; }
  74.     }
  75. }
复制代码
我的疑问是:
1.  
class provinceItem
{
public string Name { get; set; }
public int Id { get; set; }
} 这个类在这里的作用是什么?(望学长讲解详细一点)

2.
provinceItem item = new provinceItem();                                      //产生一个Item对象
provinceItem item = (provinceItem)cmb省.SelectedItem;      
这两行代码中的item是同一个item吗?

3.
provinceItem item = (provinceItem)cmb省.SelectedItem;        这个item里边包含两个信息,一个是省Id,一个是省的名字
这个item里边是包含两个信息,一个是省Id,一个是省的名字 ,对吗 ?
我是真心寻求答案!

作者: 七里香    时间: 2013-9-24 12:25
问题1.你声明的 provinceItem其实是一个类,也就是说把省份作为一个对象,而该类中有name和id的两个属性。而在你的combox控件中items存储的就是一个省的对象。当然那不是一个方法{:soso_e113:}。
问题2.............................额两个item确实是同一个。这个你没又搞错哦,但是问题一是一个类而且不是一个静态类(没有static修饰)所以你要通过new关键字实例化一个item对象哦。不通过new的话,把问题一种声明的类设为静态类吧。{:soso_e120:}
问题3.由于item是proviceitem类的一个对象而provinceItem item = (provinceItem)cmb省.SelectedItem语句相当于给item对象赋值,也就是给item的name和id属性赋值。恭喜你答对了{:soso_e113:}。
还有友情提示一下
InitializeComponent();
            string dataDir = AppDomain.CurrentDomain.BaseDirectory;
            if (dataDir.EndsWith(@"\bin\Debug\")
                || dataDir.EndsWith(@"\bin\Release\"))
            {
                dataDir = System.IO.Directory.GetParent(dataDir).Parent.Parent.FullName;
                AppDomain.CurrentDomain.SetData("DataDirectory", dataDir);
            }
这段代码你不用放在窗体代码里面。只要放在program.cs文件的mian()方法里的最上面就ok了哦,真的是友情提示哦!亲。希望能帮到你{:soso_e100:}
作者: ┾——黑马    时间: 2013-9-24 12:40
        private void button1_Click(object sender, EventArgs e)
        {
            int length = phone.Text.Length;
            if (length <= 0 || length > 11 || length < 7)
            {
                MessageBox.Show("请输入至少输入您手机号的前七位有效数字!");
                phone.Text = "";
                phone.Focus();
                return;
            }
            string phoneNum = phone.Text.Substring(0,7);
            using (SqlConnection conn = new SqlConnection(
                "Data Source=.;Initial Catalog=Test;User ID=sa;Password=201217xu"))
            {
                conn.Open();
                using (SqlCommand cmd = conn.CreateCommand())
                {
                    cmd.CommandText = "select * from T_TelNum where StartTelNum=@s";
                    cmd.Parameters.Clear();
                    cmd.Parameters.Add(new SqlParameter("@s",phoneNum));

                    SqlDataAdapter adapter = new SqlDataAdapter(cmd);
                    DataSet dataSet = new DataSet();
                    adapter.Fill(dataSet);
                    DataTable tables=dataSet.Tables[0];

                    foreach (DataRow line in tables.Rows)
                    {
                        string telArea=(string)line["TelArea"];
                        string telType=(string)line["TelType"];
                        string str=telArea+"   "+telType;
                        MessageBox.Show(str);
                        phone.Text = "";
                        phone.Focus();
                        return;
                    }
                    MessageBox.Show("查询不到你的号码归属地!");
                    phone.Text = "";
                    phone.Focus();
                }
            }
        }

        private void phone_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.KeyCode == Keys.Enter)
            {
                this.button1_Click(button1,null);
            }
        }

这是我自己看杨中科老师视频以后,自己加的一点查询手机号码实现的代码!希望对你有帮助
作者: ┾——黑马    时间: 2013-9-24 12:43
加了点注释,希望对你有帮助      
  private void button1_Click(object sender, EventArgs e)
        {
            int length = phone.Text.Length;//这个是你输入手机号的文本框
            if (length <= 0 || length > 11 || length < 7)
            {
                MessageBox.Show("请输入至少输入您手机号的前七位有效数字!");
                phone.Text = "";
                phone.Focus();
                return;
            }
            string phoneNum = phone.Text.Substring(0,7);//截取前七位就可以查询了
            using (SqlConnection conn = new SqlConnection(
                "Data Source=.;Initial Catalog=Test;User ID=sa;Password=201217xu"))
            {
                conn.Open();
                using (SqlCommand cmd = conn.CreateCommand())
                {
                    cmd.CommandText = "select * from T_TelNum where StartTelNum=@s";
                    cmd.Parameters.Clear();
                    cmd.Parameters.Add(new SqlParameter("@s",phoneNum));

                    SqlDataAdapter adapter = new SqlDataAdapter(cmd);
                    DataSet dataSet = new DataSet();
                    adapter.Fill(dataSet);
                    DataTable tables=dataSet.Tables[0];

                    foreach (DataRow line in tables.Rows)
                    {
                        string telArea=(string)line["TelArea"];
                        string telType=(string)line["TelType"];
                        string str=telArea+"   "+telType;
                        MessageBox.Show(str);
                        phone.Text = "";
                        phone.Focus();
                        return;
                    }
                    MessageBox.Show("查询不到你的号码归属地!");
                    phone.Text = "";
                    phone.Focus();
                }
            }
        }

        private void phone_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.KeyCode == Keys.Enter)//用户直接在文本框按回车键就可以查询
            {
                this.button1_Click(button1,null);
            }
        }
作者: ┾——黑马    时间: 2013-9-24 12:50
不好意思哈,刚刚看错题目了{:soso_e110:}!这是我这样实现的省市选择,感觉蛮简单的!希望对你有帮助!{:soso_e113:}

<Window x:Class="ADONET基础.CitySelectWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="省市浏览" Height="400" Width="600" Background="#FF49CD35"
        BorderBrush="#FF306C27" Foreground="#FF872424" WindowStartupLocation="CenterScreen" ResizeMode="CanMinimize">
    <Grid>
        
        <StackPanel Orientation="Horizontal" HorizontalAlignment="Center">
            <ListBox DisplayMemberPath="AreaName" Name="lbPro" Height="300" Width="150" Loaded="lbPro_Loaded" SelectionChanged="lbPro_SelectionChanged"></ListBox>
            <ListBox DisplayMemberPath="AreaName" Name="lbCity" Height="300" Width="150" SelectionChanged="lbCity_SelectionChanged"/>
            <ListBox DisplayMemberPath="AreaName" Name="lbxian" Height="300" Width="150"></ListBox>
        </StackPanel>
        
    </Grid>
</Window>



using System;
using System.Collections.Generic;
using System.Data;
using System.Data.SqlClient;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;

namespace ADONET基础
{
    /// <summary>
    /// CitySelectWindow.xaml 的交互逻辑
    /// </summary>
    public partial class CitySelectWindow : Window
    {
        public CitySelectWindow()
        {
            InitializeComponent();
        }

        bool temp = true;

        private void lbPro_Loaded(object sender, RoutedEventArgs e)
        {
            DataTable table = SqlHelper.ExecuteDataTable("select * from AreaFull");

            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"];
                listPro.Add(area);
            }

            lbPro.ItemsSource = listPro;
        }

        private List<Area> show(Area selectArea)
        {
            DataTable table = SqlHelper.ExecuteDataTable("select * from AreaFull where AreaPid=@pid", new SqlParameter("@pid", selectArea.AreaId));
            List<Area> list = new List<Area>();
            foreach (DataRow dataRow in table.Rows)
            {
                Area area = new Area();
                area.AreaId = (int)dataRow["AreaId"];
                area.AreaName = (string)dataRow["AreaName"];
                list.Add(area);
            }
            return list;
        }

        private void lbPro_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            Area selectArea = (Area)lbPro.SelectedItem;
            List<Area> listCity = show(selectArea);

            if (lbxian.ItemsSource != null)
            {
                temp = false;//这个很重要,如果lbXian已经没有对象了,就不要再让temp标记为false了
                lbxian.ItemsSource = null;
            }
            lbCity.ItemsSource = listCity;
        }

        private void lbCity_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            if (temp)
            {
                Area selectArea = (Area)lbCity.SelectedItem;
                List<Area> listXian = show(selectArea);
                lbxian.ItemsSource = listXian;
            }
            else
            {
                temp = true;
            }
        }
    }
}

作者: ┾——黑马    时间: 2013-9-24 12:54
如果你的命名和杨中科老师视频里面的命名都是一样的,话,就很容易看懂了,直接复制过去就可以运行了!

作者: Always.    时间: 2013-9-24 12:55
┾——黑马 发表于 2013-9-24 12:54
如果你的命名和杨中科老师视频里面的命名都是一样的,话,就很容易看懂了,直接复制过去就可以运行了!
...

就是因为老师讲的我不懂,我才问的。不然干嘛 ?

作者: ┾——黑马    时间: 2013-9-24 13:00
Always. 发表于 2013-9-24 12:55
就是因为老师讲的我不懂,我才问的。不然干嘛 ?

老师视频里面其实有个bug,就是当第三个ListBox有内容的时候再点击第一个listBox程序就会报错,如果你有兴趣的话你可以看一下,我这个bug给解决了!当初也想了好久,其实也蛮简单的

作者: Always.    时间: 2013-9-24 13:04
七里香 发表于 2013-9-24 12:25
问题1.你声明的 provinceItem其实是一个类,也就是说把省份作为一个对象,而该类中有name和id的两个属性。 ...

明白了。谢谢
你说的我好像都明白,但是老是感觉这个题没有吃透。。
我再想想。。
嘻嘻,
那段代码确实要放在
program.cs文件的mian(),是我疏忽了。
但是为什么,我那样也可以实现呢 ?

作者: Always.    时间: 2013-9-24 13:06
┾——黑马 发表于 2013-9-24 13:00
老师视频里面其实有个bug,就是当第三个ListBox有内容的时候再点击第一个listBox程序就会报错,如果你有 ...

我只想说,你说的题目和我 说的不是一道题。里边只有个省选择器,一个市选择器。

作者: Always.    时间: 2013-9-24 13:17
七里香 发表于 2013-9-24 12:25
问题1.你声明的 provinceItem其实是一个类,也就是说把省份作为一个对象,而该类中有name和id的两个属性。 ...

恩恩。你说的我都明白了。。但是好像我没有把我的疑问表达出来,不知道怎的我老是觉得没有把这个题目吃透,说哪里不知道又说不出来。你们有这样的感觉吗 ?
那段代码放在program.cs文件的mian()可以实现,但是我那样同样也有结果啊 ? 两者有啥子区别吗?
谢谢学长的耐心解答!嘻嘻

作者: 七里香    时间: 2013-9-24 13:53
Always. 发表于 2013-9-24 13:04
明白了。谢谢
你说的我好像都明白,但是老是感觉这个题没有吃透。。
我再想想。。

这就要从winform窗体执行的顺序说起了,那么main方法是整个程序的入口。也就是说程序都是从那个方法开始执行的。然后执行Application.Run(new Form1());就会执行到加载你的窗口,然后再执行窗体里的代码。但是如果你的窗体是并列的,比如说一个新的窗体的时候你就得每个窗体都要写那段代码才能够执行。所以最优化的方法还是在main函数前执行那样你就不用在多个窗体前都加那段代码了哦。

作者: Always.    时间: 2013-9-24 14:35
七里香 发表于 2013-9-24 13:53
这就要从winform窗体执行的顺序说起了,那么main方法是整个程序的入口。也就是说程序都是从那个方法开始 ...

OK  I see/,thanks again





欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2