1、数据库的创建

c#读取数据库中的值,首先需要创建一个数据库,创建数据库之后,创建表格即可,再根据自己的需求,创建自己的table即可,最重要的是通过c#与数据库链接,去访问数据库中的内容。

2、c#链接数据库

      首先需要引入NpgsqlTypes 包,紧接着声明一个全局变量con作为连接符号,在连接数据库的过程中需要主机ip,端口号port,数据库名称,数据库用户名称,以及数据库的密码,如下面代码所示:

            var cs = "Host=127.0.0.1;Port=5432;Database=test;Username=postgres;Password=yc;";
            con = new NpgsqlConnection(cs);

c#访问数据库主要是增删查改四个操作,具体代码如下:

using Npgsql;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using NpgsqlTypes;

namespace DataBase
{
   
    internal class database
    {
        //数据库链接
        NpgsqlConnection con;   //定义一个全局的数据库
        List<string> list = new List<string>(3);
        List<string[]> list2 = new List<string[]>();
        public database()
        {
            var cs = "Host=127.0.0.1;Port=5432;Database=test;Username=postgres;Password=yc;";
            con = new NpgsqlConnection(cs);
            
        }
         

        //向数据库中插入数据
        public void Insert_Data(string usrname, string Permission, string Num)
        {
            try
            {
                con.Open();
                string insertQuery = "INSERT INTO usr (name, rule,pnum) VALUES ('" + usrname + "' , '" + Permission + "','" + Num + "' )";
                NpgsqlCommand cmd = new NpgsqlCommand(insertQuery, con);

                cmd.Parameters.AddWithValue("@name", usrname);
                cmd.Parameters.AddWithValue("@rule", Permission);
                cmd.Parameters.AddWithValue("@pnum", Num);
                cmd.ExecuteNonQuery();
            }
            catch (NpgsqlException ex)
            {
                Console.Write("连接失败" + ex.Message);
            }

            finally
            {
                con.Close();
            }
        }
        //通过限定字符str1,读取特定的行数据,并且以List<string>的格式返回回去
        public List<string> Read_Data(string str1)
        {
            try
            {
                con.Open();
                string select = "SELECT name,rule,pnum FROM usr where name ='" + str1 + "'";
                //string selectQuery = "SELECT * from  usr";
                NpgsqlCommand cmd = new NpgsqlCommand(select, con);
                NpgsqlDataReader dataReader = cmd.ExecuteReader();
                while (dataReader.Read())
                {
                    list.Add(dataReader["name"].ToString());
                    list.Add(dataReader["rule"].ToString());
                    list.Add(dataReader["pnum"].ToString());
                    
                    return list;
                }
            }
            catch (NpgsqlException ex)
            {
                Console.Write("连接失败" + ex.Message);
            }
            finally
            {
                con.Close();

            }
            return null;
        }
        //读取数据库中的所有数据,并将数据返回主线程
        public ref List<string[]> Read_ALL()
        {
            try
            {
                con.Open();
                string select = "SELECT * FROM usr ";
                NpgsqlCommand cmd = new NpgsqlCommand(select, con);
                NpgsqlDataReader dataReader = cmd.ExecuteReader();
                string[] list = new string[2];
                list2.Clear();
                int i = 0;
                while (dataReader.Read())
                {
                    list2.Add((string[])list.Clone());
                    
                    list2[i][0]=dataReader["name"].ToString();
                    list2[i][1]=dataReader["rule"].ToString();
                    i++;

                }
                return ref list2;
            }
            catch (NpgsqlException ex)
            {
                Console.Write("连接失败" + ex.Message);
            }
            finally
            {
                con.Close();

            }
            return ref list2;
        }
        //更新数据库
        public void Update_Data(string strname, string strPermission,string newnum)
        {
            try
            {
                con.Open();
                string updateQuery = "UPDATE usr SET rule = '" + strPermission + "',pnum='"+newnum+"' WHERE name = '" + strname + "'";
                NpgsqlCommand cmd = new NpgsqlCommand(updateQuery, con);

                cmd.Parameters.AddWithValue("@newname", strname);
                cmd.Parameters.AddWithValue("@newrule", strPermission);
                cmd.Parameters.AddWithValue("@newpnum", newnum);

                cmd.ExecuteNonQuery();
            }
            catch (NpgsqlException ex)
            {
                Console.Write("连接失败" + ex.Message);

            }
            finally
            {
                con.Close();
            }
        }
        //删除数据
        public void Del_Data(string del)
        {
            try
            {
                con.Open();
                string deleteQuery = "DELETE FROM usr WHERE name ='" + del + "'";
                NpgsqlCommand cmd = new NpgsqlCommand(deleteQuery, con);
                cmd.Parameters.AddWithValue("@name", del);

                cmd.ExecuteNonQuery();
            }
            catch (NpgsqlException ex)
            {
                Console.Write("连接失败" + ex.Message);
            }
            finally
            {
                con.Close();
            }
        }
    }
    

}

访问数据库的常规操作如下:

        public void Insert_Data(string usrname, string Permission, string Num)
        {
            try
            {
                //首先打开数据库
                con.Open();   
                //然后是数据库询问语句
                string insertQuery = "INSERT INTO usr (name, rule,pnum) VALUES ('" + usrname + "' , '" + Permission + "','" + Num + "' )";
                //通过数据库的命令语句,将查询语句送入数据库连接中
                NpgsqlCommand cmd = new NpgsqlCommand(insertQuery, con);

                cmd.Parameters.AddWithValue("@name", usrname);
                cmd.Parameters.AddWithValue("@rule", Permission);
                cmd.Parameters.AddWithValue("@pnum", Num);
                cmd.ExecuteNonQuery();
            }
            catch (NpgsqlException ex)
            {
                Console.Write("连接失败" + ex.Message);
            }

            finally
            {
                //每次访问数据库之后,进行关闭
                con.Close();
            }
        }

3、C#中的DataGridView控件

DataGridView这个控件类似于一个表格,主要是一个列控件,控件属性主要是对列进行操作,控制有几列,列头的名称。当然这个控件还可以直接读取数据库的数据,即选择数据源那里即可,这个我倒是不知道怎么操作,可以自己研究一下。

 针对该控件可能,控件运行之后,第一列会存在空列,最后一行存在空行的现象,并且点击每列的表头的时候,表格会自动给你排序,可以设置如下的属性,完成删除空列、空行并且不让每列进行自主排序的需求:

 dataGridView1.RowHeadersVisible = false;  //取消空白列
 dataGridView1.AllowUserToAddRows = false;
 for (int i = 0; i < this.dataGridView1.Columns.Count; i++)
 {
     this.dataGridView1.Columns[i].SortMode = DataGridViewColumnSortMode.NotSortable;
 }

如何将外来的数据,显示在DataGridView上呢,主要是通过创建行,并且行元素创建单元格的方式进行访问,如下面代码所示:

        public void GetDataReader(ref List<string[]> reader)
        {

            this.dataGridView1.Rows.Clear();
            foreach (string[] list in reader)
            { 
                DataGridViewRow row = new DataGridViewRow();
                row.CreateCells(this.dataGridView1);
                row.Cells[0].Value = list[0];
                row.Cells[1].Value = list[1];
                this.dataGridView1.Rows.Add(row);
            }
        }

4、DataGridView的属性

点击行的时候,将该行的信息获取到 

private void dataGridView1_CellClick(object sender, DataGridViewCellEventArgs e)

        private void dataGridView1_CellClick(object sender, DataGridViewCellEventArgs e)
        {
            int index = dataGridView1.SelectedCells[0].RowIndex;
            var name = dataGridView1.Rows[index].Cells[0].Value;
            var rule = dataGridView1.Rows[index].Cells[1].Value;
            this.usrname.Text = name.ToString();
            this.limit.Text = rule.ToString();
        }

在DataGridView的每一行的最后一个格子,放置一个按钮,并且拥有按钮响应时间的代码如下:

//在窗口load的时候,进行按钮的创建
private void UsrPro_Load(object sender, EventArgs e)
{
   DataGridViewButtonColumn btn = new DataGridViewButtonColumn();
   btn.Name = "Modify";
   btn.HeaderText = "重置密码";
   btn.DefaultCellStyle.NullValue = "修改";
   dataGridView1.Columns.Add(btn);
 }       


private void dataGridView1_CellContentClick(object sender, DataGridViewCellEventArgs e)
{
   if (this.dataGridView1.Columns[e.ColumnIndex].Name == "Modify")
   {
    DialogResult res = MessageBox.Show("是否更改密码","Warning",MessageBoxButtons.YesNoCancel, MessageBoxIcon.Asterisk);
        if(res == DialogResult.Yes) 
        {
          int index = dataGridView1.SelectedCells[0].RowIndex;
           //获取所在行
          var name = dataGridView1.Rows[index].Cells[0].Value;
          var rule = dataGridView1.Rows[index].Cells[1].Value;
          this.Invoke(usrpsdchange, name.ToString(), rule.ToString());
         }
    }
}

具体效果如下所示:

5、c#的委托事件

c#如何将子窗口的值传递给父窗口呢,主要是通过委托和事件,委托和事件,其实相当于特定类型的函数指针,该委托指向了父窗口的某一个函数,当子窗口触发该事件后,开始调用主窗口的函数,进行运行,如下代码所示:

首先在子窗口的文件中声明委托和事件

        //子窗口部分

        public delegate void Usr_Add(string Text1,string Text2);
        public Usr_Add usradd = null;   //必须为委托类型的事件
        //触发该事件主要依靠Invoke函数
        private void btn_Sure_Click(object sender, EventArgs e)
        {
            if(usradd!=null)
            {
                string str1 = usrname.Text;
                string str2 = limit.Text;
                this.Invoke(usradd, str1, str2);//触发到主函数的具体事件
            }
        }

主函数部分如下:

        frm_Usr.usradd       = UsrAddNew;   //函数指针,指向具体的函数
        private void UsrAddNew(string Text1, string Text2) //与委托的传递参数一致
        {
            List<string> str1 = cls_Dat.Read_Data(Text1);
            if (str1 == null)  
            {
                cls_Dat.Insert_Data(Text1, Text2, "123456");
                frm_Usr.GetDataReader(ref cls_Dat.Read_ALL());
            }
            else
            {
                cls_Dat.Update_Data(Text1, Text2, str1[2]);
            }
        }

与qt的connect机制一致。

6、c#子线程调用主线程的控件

在窗口编程过程中,难免会操控子线程去控制主线程的控件,但是直接操作会报错,因为主窗口的控件属于主线程,是不能够跨线程操作的,这是不安全的操作,所以vs直接将此操作禁止。为了让子线程控制主线程的控件,也需要使用委托和事件。具体代码如下:

       

       private delegate void DispMSGDelegate(string strMsg);
       //定义一个函数,用于子线程向窗体上的Box添加内容
       private void DispMsg(string strMsg)
       {
            //这里的InvokeRequried 表示是否有该控件的线程之外的线程访问
            //true表示真,有线程之外的线程访问
           if (this.DayRecord.InvokeRequired == false)
           {
               this.DayRecord.Items.Insert(0, strMsg);
               StaTime.Text = (++WritedCount).ToString();
               this.RunConTime.Text = (++localdayaruntime).ToString();

           }
           else
           {
               DispMSGDelegate DMSGD = new DispMSGDelegate(DispMsg);
               this.DayRecord.Invoke(DMSGD,strMsg);
           }
       }


7、c#子线程读取文件中的图像数据

            DirectoryInfo folder = new DirectoryInfo(img1path);
            while (folder.Exists)
            {
                foreach (FileInfo file in folder.GetFiles("*.png"))
                {
                    Image img = Image.FromFile(file.FullName);
                    this.pictureBox1.Image = img;
                    var now = DateTime.Now;
                    var logContent = string.Format(" {0}{1} {2} \r\n", now.ToLongDateString(), now.ToLongTimeString(), file.ToString());
                    WriteLog(logContent.ToString());
                    Thread.Sleep(timegap);
                }
            }

Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐