一步一步学习Winform系列3:新增记录——DataGridView的属性和数据banding

要点:

1、DataGridView的数据绑定(按钮的点击事件)

2、DataGridView样式设置:不可编辑、自动填充、中文列标题、交替行

3、新增部门信息——弹出新窗体,生成新的部门编号

4、新增部门信息——部门经理的下拉列表

5、新增部门信息——保存到数据库

 

延伸知识:打开文件控件——OpenFileDialog 

延伸知识:图片保存到数据的方法


 1、DataGridView的数据绑定


根据上一课的基本信息管理主界面,需要实现的效果是点击每个图片按钮可以查看相应的信息,也就是在这些按钮的点击事件中添加数据绑定。

先来实现点击上面按钮后能绑定数据到DataGridView中

1、DataGridView的数据绑定(部门信息按钮的点击事件)

(1)给本界面的cs文件添加using引用

using System.Data.SqlClient;

using NorthwindDAL;

(2)为datagridView添加数据源属性

DataSet ds= SqlHelper.ExecuteDataset(SqlHelper.GetConnSting(),CommandType.Text,"SELECT * FROM 部门表");

dataGridView.DataSource = ds.Tables[0];    

绑定完成后,为了保证测试方便,我们到Program.cs文件中临时更改一下启动窗体,将原来的Login改为基本信息管理主界面。

 

运行一下就能看到现在的界面,点击信息部门按钮看看是否能加载部门表。

 

其他按钮的表格绑定以此类推。

我们发现了几个问题:

1)        部门信息是可以任意编辑但是不影响数据库。能否让这个控件不能编辑?

2)        部门信息的数据列比较少,能否自动填充整个窗体?

3)        雇员信息的列标题是英文,能否翻译成中文?

4)        雇员信息字段很多,需要拉动水平滚动条才能看完,能否只显示关键的列?

5)        客户信息记录很多,容易看错行,能否设置交错行?

6)        产品类别的描述字段内容很多,能否完全显示?

 

这些都是对datagridView的样式要求啦,一起来看看怎么定制这个控件的效果。

 回到顶部


2、DataGridView样式设置


1)        部门信息是可以任意编辑但是不影响数据库。能否让这个控件不能编辑?

回到设计界面,对控件属性进行相应的设置

AllowUserToAddRows——是否允许用户自动增加新行

EditMode——EditProgrammatically,只允许从代码进行编辑

ReadOnly——只读模式

注意:对datagridView控件的设置是会影响所有加载到这个控件的数据的。

 

2)        部门信息的数据列比较少,能否自动填充整个窗体?

控件的属性设置可以放在代码内完成,只要点击过这个按钮,所有的按钮显示数据都会记住这个属性,因此可以在设计界面中设置自动填充,如果有特殊要求的再到代码中设置

 

比如设置了行高自动调整,则产品类别中显示效果

 

但是与此同时,雇员的显示效果就很差

 

这时可以在雇员信息的点击按钮内加上列宽的设置

dataGridView.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.DisplayedCells;

列宽与行高的设置请参考延伸知识。注意关于性能:
通过 AutoSizeColumnsMode 或者 AutoSizeRowsMode 属性所指定的单元格进行自动调整时,如果调整次数过多那么将可能导致性能下降,尤其是在行和列数比较多的情况下。在这时用 DisplayedCells 代替 AllCells 能减少非所见的单元格的调整,从而提高性能。

 

3)        雇员信息的表头是英文,能否翻译成中文?

方法一:用SQL语句转换,也就是说SELECT Name as 姓名 FROM …… 

方法二:循环设置所有的列标题

 

方法三:直接用中文名作数据库的字段名吧,一劳永逸

 

4)        雇员信息字段很多,需要拉动水平滚动条才能看完,能否只显示关键的列?

方法一:还是SQL语句的问题,这个自己考虑

方法二:把已经显示出来的列隐藏掉,对于代码是可用的,但对用户是不可见的

 

注意:这里的[]内使用的是数据库中的字段名称,不是刚刚的中文列标题

 

5)        客户信息记录很多,容易看错行,能否设置交错行?可否设置选中行样式?

 

6)        产品类别的图片能否完全显示?

其实刚刚已经讲了,还记得吗?设置什么?

 

延伸知识:内容填充

l  根据内容自动填充——部门信息

DataGridViewAutoSizeColumnsMode成员名称

说明

AllCells

列宽调整到适合列中所有单元格(包括标头单元格)的内容。

AllCellsExceptHeader

列宽调整到适合列中除标头单元格以外所有单元格内容。

ColumnHeader

列宽调整到适合列标头单元格的内容。

DisplayedCells

列宽调整到适合位于屏幕上当前显示的行中的列的所有单元格(包括标头单元格)的内容。

DisplayedCellsExceptHeader

列宽调整到适合位于屏幕上当前显示的列中的列的所有单元格(不包括标头单元格)的内容。

Fill

列宽调整到使所有列宽精确填充控件的显示区域,要求使用水平滚动的目的只是保持列宽大于DataGridViewColumn.MinimumWidth属性的值。相对列宽由相对 DataGridViewColumn.FillWeight属性值决定。

None

列宽不会自动调整。

行高的自动调整

DataGridView行的高度自动调整,可以使用DataGridView1.AutoSizeRowsMode属性实现。

 //根据Header和所有单元格的内容自动调整行的高度
DataGridView1.AutoSizeRowsMode = DataGridViewAutoSizeRowsMode.AllCells;
 

DataGridViewAutoSizeRowsMode枚举的成员如下所示: 

DataGridViewAutoSizeRowsMode成员名称

说明

AllCells

将行高调整到适合行中所有单元格(包括标头单元格)的内容。

AllCellsExceptHeaders

将行高调整到适合行中所有单元格(不包括标头单元格)的内容。

AllHeaders

将行高调整到适合行标头的内容。

DisplayedCells

将行高调整到适合屏幕上当前显示的行中所有单元格(包括标头单元格)的内容。

DisplayedCellsExceptHeaders

将行高调整到适合屏幕上当前显示的行中所有单元格(不包括标头单元格)的内容。

DisplayedHeaders

将行高调整到适合屏幕上当前显示的行标头的内容。

None

行高不自动调整。

好了,到目前为止,我们已经可以比较专业的显示出数据库的数据。以雇员信息表按钮有例,他的设置代码如下:

View Code
 //后续按钮事件依次类推
        private void btn雇员信息_Click(object sender, EventArgs e)
        {
            //利用Sqlhelper类绑定数据源
            DataSet ds = SqlHelper.ExecuteDataset(SqlHelper.GetConnSting(), CommandType.Text, "SELECT * FROM Employees");
            dataGridView.DataSource = ds.Tables[0];            

            //雇员信息的列标题改中文名
            string strFieldText = "雇员编号,所在部门,密码,姓名,头衔职务,称呼,出生日期,雇佣日期,地址,城市,地区,邮编,国家,家庭电话,扩展,照片,备注,负责人,照片地址";
            string[] arrFieldText = strFieldText.Split(',');
            for (int i = 0; i < dataGridView.Columns.Count; i++)
                dataGridView.Columns[i].HeaderText = arrFieldText[i];

            //不显示某些列,只显示关键列
            dataGridView.Columns["Password"].Visible = false;
            dataGridView.Columns["TitleOfCourtesy"].Visible = false;
            dataGridView.Columns["Address"].Visible = false;
            dataGridView.Columns["Extension"].Visible = false;
            dataGridView.Columns["Notes"].Visible = false;
            dataGridView.Columns["PhotoPath"].Visible = false;
            //dataGridView.Columns["Photo"].Visible = false;

            //设置列宽的显示
            dataGridView.AutoSizeRowsMode = DataGridViewAutoSizeRowsMode.AllCellsExceptHeaders;
            dataGridView.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.DisplayedCells;
        }

 

下一步是增加部门信息了。 

请大家先设计一个新增部门信息的窗体,注意属性与控件类型。

 

  回到顶部


4、基本信息管理模块——新增部门信息


难点:弹出新窗口、自动生成最大的编号、部门经理的下拉列表,保存到数据库

 

(1)       点击新增按钮后弹出新增部门信息的窗体

跟上次一样,申明一个新的窗体对象后,使用show的方法即可。

Form 新增部门信息= new新增部门信息();

新增部门信息.Show();

(2)       弹出窗口后自动生成部门编号

我们不满足于此,我们需要能找到当前数据库中的最大编号,然后递增1作为新部门的编号出现在新窗体,且这个编号是用户不能手动修改。

在新窗体中,我们写个方法GenerateNew部门编号吧,然后调用这个方法,将值返回给tbx部门编号。

 

View Code
/// <summary>
        /// 先取得数据库内最大的部门编号,递增1后作为新部门的编号
        /// </summary>
        /// <returns>返回新部门编号</returns>
        public static string GenerateNew部门编号()
        {
            //获得数据库中最大的部门编号
            string strMax部门编号 = (string)SqlHelper.ExecuteScalar(SqlHelper.GetConnSting(), CommandType.Text, "SELECT 部门编号 FROM 部门表 ORDER BY 部门编号 DESC");
            //给部门最大编号加1,这里需要使用到字符串处理函数——取出子串
            int 部门编号 = Convert.ToInt32(strMax部门编号.Substring(2)) + 1;
            //返回这个编号,这里还需要判断一下,如果你的编号是int型的就不需要判断直接返回
            if (部门编号 >= 100)
            {
                return "BM" + 部门编号;
            }
            else if (部门编号 >= 10)
            {
                return "BM0" + 部门编号;
            }
            else
            {
                return "BM00" + 部门编号;
            }
        }

(3)       窗体加载时,自动将所有雇员都放在下拉列表里面

View Code
 private void 新增部门信息_Load(object sender, EventArgs e)
        {
            //为comboBox添加数据源
            string strSql = "SELECT FirstName FROM Employees";
            DataSet ds = SqlHelper.ExecuteDataset(SqlHelper.GetConnection(), CommandType.Text, strSql);
            cbx部门经理.DataSource = ds.Tables[0];
            cbx部门经理.DisplayMember = "FirstName";
            cbx部门经理.ValueMember = "FirstName";
        }

 

延伸知识:下拉列表控件——ComboBox的常用属性设置

1)Text属性:获取当前显示的文本

2)SelectedText属性:获得当前选中的文本(控件获得光标且DropDown属性不为DropDownList)

 注意:但应注意,所选内容会因用户交互而自动更改。如Button的Click事件中,SelectedIndexChanged 或 SelectedValueChanged 事件中,此属性会返回空字符串(参见MSCN:http://msdn.microsoft.com/zh-cn/partners/system.windows.forms.combobox.selectedtext(VS.90).aspx )

3)SelectedValue属性:当前显示项对应的Value值(仅在绑定数据源时,设置了ValueMember时才可以用)

4)SelectedItem属性:控件当前选中项

5)SelectedIndex属性:当前选中项的索引

 

(4)       新增一条部门记录(见证奇迹的时刻到了)

有了Sqlhelper啥也不用愁了,只需要准备参数就可以了,这回我们使用的是sqlhelper中ExecuterNonQuery的方法。大家尽量自己先写写,再对照代码。

 

 

请大家根据数据库表结构设计一个新增雇员的界面

 

与新增部门信息不同的是:为了能否上传雇员招聘,我们还需要拖入一个OpenfileDiaLog控件

 

这个窗体内的雇员编号、所在部门、新增按钮事件跟前面的新增部门信息是一样,请大家自行完成。

 

问题接二连三的出现了:

1、  现在的新增按钮总是弹出的是新增部门信息,怎么能根据datagridView的内容弹出相应的窗体呢?

2、  这个图片如何操作?如果保存到数据?

请先百度看看或者根据下面的延伸知识能否解决这两个问题,解决办法将于下一课公布。

  回到顶部


延伸知识:打开文件控件——OpenFileDialog


Windows 窗体的 OpenFileDialog(打开文件对话框)组件是一个预先配置的对话框。它与 Windows 操作系统的“打开文件”对话框相同。该控件是从 CommonDialog 类继承的。

  在基于 Windows 的应用程序中,可该组件实现简单的文件选择,而不必配置自己的对话框。利用标准的 Windows 对话框,可以创建用户所熟悉的应用程序界面。
OpenFileDialog 组件的主要属性包括:

  (1)  Title 属性:获取或设置文件对话框标题。默认值为空字符串("")。
如果标题为空字符串,系统将使用默认标题打开

  (2)  Multiselect 属性:获取或设置一个值,该值指示对话框是否允许选择多个文件。
  如果对话框允许同时选定多个文件,则为 true;反之,则为 false。默认值为 false。使用 FileNames 属性可访问选定文件名的完整列表。


  (3)  ShowReadOnly 属性:获取或设置一个值,该值指示对话框是否包含只读复选框。
如果对话框包含只读复选框,则为 true;否则为 false。默认值为 false

  (4)  ReadOnlyChecked 属性:获取或设置一个值,该值指示是否选定只读复选框。
  如果选中了只读复选框,则为 true;反之,则为 false。默认值为 false

  (5)  Filter 属性:获取或设置当前文件名过滤字符串,该字符串决定对话框的文件类型框中出现的选择内容。
  对于每个过滤选项,过滤字符串都包含过滤条件说明,后接一垂直线条(|)和过滤模式。不同过滤选项的字符串由垂直线条隔开。例如:
  "Text files (*.txt)|*.txt|All files (*.*)|*.*"
  如果要将多个过滤模式添加到过滤条件中,可用分号将文件类型分隔开,例如:
  "Image Files(*.BMP;*.JPG;*.GIF)|*.BMP;*.JPG;*.GIF|All files (*.*)|*.*"
  使用 FilterIndex 属性设置第一个显示给用户的过滤选项。


  (6)  FilterIndex 属性:获取或设置文件对话框中当前选定过滤条件的索引。
默认值为 1。第一个过滤条目的索引值为 1

  (7)  FileName 属性:获取或设置一个包含在文件对话框中选定的文件名的字符串。也就是在对话框中选择的文件名,默认值为空字符串("")。
  文件名既包含文件路径也包含扩展名。如果未选定文件,将返回空字符串。

  (8)  FileNames 属性:获取对话框中所有选定文件的文件名。
  属性值是一个 String 类型数组。每个文件名都既包含文件路径又包含文件扩展名。如果未选定文件,该方法将返回空数组。

  该组件的主要方法包括:

  (1)  ShowDialog 方法:在运行时显示对话框。

  (2)  OpenFile 方法:打开用户选定的具有只读权限的文件,该文件由 FileName 属性指定。
  使用该方法可从对话框以只读方式快速打开文件。

  回到顶部


延伸知识:图片保存到数据的方法


方法一:在数据库中添加图片名字,然后把图片存在指定的文件夹中。 

           这种方法存起来简单,但是删除的时候麻烦。 

           存:在数据库中建一个文本字段(access)或者varchar字段(sqlserver)长度能放上一张图片即可 

           过程:就是一般的存的insert into 

    举个例子:sql数据库中有一个id字段 自增类型 一个name字段,用于存放图片名称的类型是varchar类型。这winform界面中你可以拖动一个TextBox,用于存放路径,一个Button这个就不说了,还有一个openFileDialog 

                     

View Code
   if (this.openFileDialog1.ShowDialog() == DialogResult.OK)

 

                          {

 

                               this.textBox1.Text = openFileDialog1.FileName;

 

                          } //打开路径,必不可少的     这些都是是在button单击事件里完成的

 

                          if (openFileDialog1.FileName.Length > 0) // 判断openFileDialog1路径的长度

 

                           {

 

                                  string oldName = openFileDialog1.FileName;            //定义一个string类型的变量 用于存放【文件路径】

 

                                   string[] splitName = oldName.Split('.');                     //为获取文件的扩展名做准备的

 

                                   string ext = splitName[splitName.Length - 1];          //文件的扩展名

 

                                    if (ext == "jpg" || ext == "gif" || ext == "bmp" || ext == "JPG")   //限制上传图片的格式

 

                                    {

 

                                         string dbName = DateTime.Now.ToString("yyyyMMddhhmmss") + "." + ext; //给上传的图片起个名字!以时间命名

 

                                         string newName = AppDomain.CurrentDomain.BaseDirectory  + dbName;  //新路径!这是个相对路径

 

                                         File.Copy(oldName, newName, true);  //把文件从以前的路径复制到新的路径中去

 

                                         //下面就开始添加到数据库里面了

 

                                         string constring="";//数据库的连接字符串

 

                                         using (SqlConnection con=new SqlConnection (constring))

 

                                          {

 

                                              con.open();

 

                                              stirng sql="insert into shujukuname (name) values(@name)"; //因为id自增的这里只需要添加图片名称

 

                                              SqlCommand cmd = new SqlCommand(sql,con);

 

                                              cmd.Parameters.Add("@name",SqlDbType.VarChar).Value=TextBox1.Text.Trim();

 

                                              cmd.ExecuteNonQuery();

 

                                              con.Close();

 

                                          }

 

                                    }                    

 

                           }             

 

方法二:直接把图片添加在sqlserver中 

首先要有一个image或者binary类型的字段,这种是以二进制形式插入到数据库中, 清理资源

View Code
FileStream fs = new FileStream(pathName, System.IO.FileMode.Open, System.IO.FileAccess.Read);

                 byte[] buffByte = new byte[fs.Length];

                 fs.Read(buffByte, 0, (int)fs.Length);

                 fs.Close();                                        //数据库字段为image类型,将图片转化为byte[],保存到数据库

     

                 SqlConnection   db   =   new   SqlConnection(strConn);

                 db.Open();

 

                 string   strSQL   =   "INSERT   INTO   shujuktable (name)   values   (@name) ";

                 SqlCommand   cmd   =   new   SqlCommand(strSQL,   db);

                 cmd.Parameters.Add( "@name",   SqlDbType.Image);

                 cmd.Parameters[ "@name"].Value   =   buffByte;

 

                 cmd.ExecuteNonQuery();                                       //保存图片的过程

 

 

转载于:https://www.cnblogs.com/chensenling/archive/2013/03/07/2948148.html

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值