C# Winform 三层架构

Posted 熊思宇

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C# Winform 三层架构相关的知识,希望对你有一定的参考价值。

一、介绍

三层架构是 C# 桌面开发中比较常用的框架,是由 表示层(UI)、业务逻辑层(BLL)和数据访问层(DAL)三层架构组成,目的是为了 “高内聚,低耦合”。开发人员分工更明确,将精力更专注于应用系统核心业务逻辑的分析、设计和开发,加快项目的进度,提高了开发效率,有利于项目的更新和维护工作。

从三层架构可以看到,很类似于 Web 前端开发的 MVC 框架(视图View,模型Model,控制Contorller),但本质上也有不同的地方,比如都有视图(三层中叫 UI),Model ,三层中没有 Contorller,但 BLL 层和 Contorller 很类似。

一个项目如果用到了三层架构,这就必然要涉及到数据库,否则就没有必要用三层架构了,下面用一张图来表示,我百度看了很多的帖子,三层架构写的基本是有一些差异的,如果你看的资料和我写的不一样,那都是正常的。

另外,各种项目根据自己的需求来,并不是所有的PC软件都要求用三层架构,用程序集划分了代码的逻辑,才是三层架构真正的意义所在。现在网上已经有很多三层架构自动生成生成软件,可以根据 sqlserver 数据库一键生成,但基本都是2016年之前的软件了,后面也没再更新了,有需要的话可以去试试。

二、搭建三层架构

新建一个基于.net6 的 winform 项目,就以登陆功能作为演示,界面如下

1.Model

添加一个 .net6 类库,取名 Model(存储数据库字段),在里面添加一个类 UserInfo

代码:

namespace Model

    public class UserInfo
    
        public string? UserName  get; set; 
        public string? Password  get; set; 
    

一般你数据库用户表的所有字段都要写出来,主要是方便后面将查询的数据以类对象的方式返回回来。

2.DAL

添加一个 .net6 类库,取名 DAL(数据访问层),在里面添加一个类 SqlServerHelper,这里看你用的什么数据库,如果是 mysql 就用 mysql 的查询方式,c# 查询 mysql 和 sqlserver 数据库我都有写相关的教程,有需要的可以去看看

C# 连接 SqlServer 数据库_熊思宇的博客-CSDN博客_c连接sqlserver数据库

C# 连接 MySQL 数据库_熊思宇的博客-CSDN博客_c# mysql

SqlServerHelper.cs

using System.Data;
using System.Data.SqlClient;
 
namespace SqlServer

    internal class SqlServerHelper
    
        /// <summary>
        /// 连接字符串
        /// </summary>
        private string strconn = string.Empty;
 
        public SqlServerHelper(string conn)
        
            //读取配置文件
            //strconn = ConfigurationManager.AppSettings["Conn"].ToString();
            //strconn = ConfigurationManager.ConnectionStrings["ConnectionString"].ToString();
            strconn = conn;
        
 
        /// <summary>
        /// 执行增删改SQL语句
        /// </summary>
        /// <param name="cmdText">SQL语句</param>
        /// <returns></returns>
        public int ExecuteNonQuery(string cmdText)
        
            using (SqlConnection conn = new SqlConnection(strconn))
            
                conn.Open();
                return ExecuteNonQuery(conn, cmdText);
            
        
 
        /// <summary>
        /// 执行增删改SQL语句
        /// </summary>
        /// <param name="conn">SqlConnection</param>
        /// <param name="cmdText">SQL语句<</param>
        /// <returns></returns>
        public int ExecuteNonQuery(SqlConnection conn, string cmdText)
        
            int res;
            using (SqlCommand cmd = new SqlCommand(cmdText, conn))
            
                cmd.CommandType = CommandType.Text;
                res = cmd.ExecuteNonQuery();
                if (conn.State == ConnectionState.Open)
                
                    conn.Close();
                    conn.Dispose();
                
            
            return res;
        
 
        /// <summary>
        /// 执行查询SQL语句
        /// </summary>
        /// <param name="cmdText">SQL语句</param>
        /// <returns></returns>
        public DataTable ExecuteDataTable(string cmdText)
        
            using (SqlConnection conn = new SqlConnection(strconn))
            
                conn.Open();
                return ExecuteDataTable(conn, cmdText);
            
        
 
        /// <summary>
        /// 执行查询SQL语句
        /// </summary>
        /// <param name="conn">SqlConnection</param>
        /// <param name="cmdText">SQL语句</param>
        /// <returns></returns>
        private DataTable ExecuteDataTable(SqlConnection conn, string cmdText)
        
            DataTable dt = new DataTable();
            using (SqlCommand cmd = new SqlCommand(cmdText, conn))
            
                cmd.CommandType = CommandType.Text;
                using (SqlDataAdapter sda = new SqlDataAdapter(cmd))
                
                    sda.Fill(dt);
                    if (conn.State == ConnectionState.Open)
                    
                        conn.Close();
                        conn.Dispose();
                    
                
            
            return dt;
        
 
        /// <summary>
        /// 执行查询SQL语句
        /// </summary>
        /// <param name="cmdText">SQL语句</param>
        /// <returns></returns>
        public DataTable ExecuteQuery(string cmdText)
        
            using (SqlConnection conn = new SqlConnection(strconn))
            
                conn.Open();
                return ExecuteQuery(conn, cmdText);
            
        
 
        /// <summary>
        /// 执行查询SQL语句
        /// </summary>
        /// <param name="conn">SqlConnection</param>
        /// <param name="cmdText">SQL语句</param>
        /// <returns></returns>
        public DataTable ExecuteQuery(SqlConnection conn, string cmdText)
        
            DataTable dt = new DataTable();
            using (SqlCommand cmd = new SqlCommand(cmdText, conn))
            
                using (SqlDataReader sdr = cmd.ExecuteReader())
                
                    dt.Load(sdr);
                    sdr.Close();
                    sdr.Dispose();
                    if (conn.State == ConnectionState.Open)
                    
                        conn.Close();
                        conn.Dispose();
                    
                
            
            return dt;
        
 
    

如果确少对应的插件,可以自己装一个

新建一个类 UserHandle,用来查询数据库并返回数据

using System.Data;

namespace DAL

    public class UserHandle
    
        private const string Conn = "server=.;dataBase=Test;uid=sa;pwd=123456";
        private static SqlServerHelper SqlServerHelpers = new SqlServerHelper(Conn);

        /// <summary>
        /// 用户登录
        /// </summary>
        /// <param name="name"></param>
        /// <param name="pwd"></param>
        /// <returns></returns>
        public static DataTable UserLogin(string name ,string pwd)
        
            // SQL 语句根据个人情况来写
            string sql = "SELECT * FROM **********";
            return SqlServerHelpers.ExecuteDataTable(sql);
        

        /// <summary>
        /// 获取用户的所有数据
        /// </summary>
        /// <param name="name"></param>
        /// <returns></returns>
        public static DataTable GetUserData(string name)
        
            // SQL 语句根据个人情况来写
            string sql = "SELECT * FROM *************";
            return SqlServerHelpers.ExecuteDataTable(sql);
        
    

3.BLL

添加一个 .net6 类库,取名 BLL(业务逻辑层),由于后面的代码需要获取到数据库数据,所以要添加 DAL 和 Model 程序集 的引用

 添加一个类 LoginHandle

using DAL;
using Model;
using System.Data;

namespace BLL

    public class LoginHandle
    

        /// <summary>
        /// 用户登录
        /// </summary>
        /// <param name="username">用户名</param>
        /// <param name="password">密码</param>
        /// <returns>是否能够登录</returns>
        public static bool UserLogin(string username, string password)
        
            DataTable dataTable = UserHandle.UserLogin(username, password);
            if (dataTable == null || dataTable.Rows.Count == 0)
            
                Console.WriteLine("查询的数据为空");
                return false;
            

            string? user = dataTable.Rows[0][0].ToString();
            string? pwd = dataTable.Rows[0][1].ToString();
            if (username.Equals(user) && password.Equals(pwd))
            
                return true;
            

            return false;
        

        /// <summary>
        /// 获取用户的所有数据
        /// </summary>
        /// <param name="username"></param>
        /// <returns></returns>
        public static UserInfo? GetUserData(string username)
        
            DataTable dataTable = UserHandle.GetUserData(username);
            if (dataTable == null || dataTable.Rows.Count == 0)
            
                Console.WriteLine("查询的数据为空");
                return null;
            

            UserInfo userInfo = new UserInfo();
            userInfo .UserName = dataTable.Rows[0][0].ToString();
            userInfo .Password = dataTable.Rows[0][1].ToString();

            return userInfo;
        
    

4.UI

UI层就是创建项目时的 winform 项目,上面的工作完成后,配置大概就如下界面

接下来就添加项目引用了,将 BLL和 Model 层添加进来

给界面的登录按钮,添加点击事件

using BLL;
using Model;

namespace 三层架构Demo

    public partial class Form1 : Form
    
        public Form1()
        
            InitializeComponent();
        

        private void Button_Login_Click(object sender, EventArgs e)
        
            string username = TextBox_UserName.Text;
            string password = TextBox_Password.Text;

            if(string.IsNullOrEmpty(username) || string.IsNullOrEmpty(password))
            
                Console.WriteLine("输入框不能为空");
                return;
            

            //第一种方式
            bool result = LoginHandle.UserLogin(username, password);
            if(result)
            
                Console.WriteLine("登录成功!");
                //跳转界面
                //....
            
            else
            
                Console.WriteLine("登录失败");
            


            //第二种方式
            UserInfo? userInfo = LoginHandle.GetUserData(username);
            if(userInfo != null)
            
                if(userInfo.Password != password)
                
                    Console.WriteLine("密码不正确");
                    return;
                

                Console.WriteLine("登录成功!");
            
        
    

 源码:点击下载

结束

如果这个帖子对你有所帮助,欢迎 关注 、点赞 、留言

end

Winform入门见解

    winform算是C#比较快速的入门的一个了,简单的控件拖拽然后写上每个控件对应的事件。然后就可以了。需要美观的点 可以用Skin皮肤就完成了。我们先不说复杂的,就来个普通的三层架构来增删改查 分页和导出。 
           环境 Vs2017+sql server2008r2 框架4.0

   首先创建新的解决方案输入你的名字。然后在解决方案右键选择添加新项目,添加类库。这里就不用图示来演示如何创建了。先建立Model层。三层架构我也不用说了,不会的可以百度。Model层创建完后,新建类。类名和你的数据库表名一样。数据库字段对应的就是类的属性。

技术分享
 1 using QX.DBHelpers.Attributes;
 2 using System;
 3 using System.Collections.Generic;
 4 using System.Linq;
 5 using System.Text;
 6 
 7 namespace Qx_SmkjItem.Model
 8 {
 9     /// <summary>
10     /// 日志信息
11     /// </summary>
12     [TableInfo(Name = "log_Info")]
13     public class log_Info
14     {
15         /// <summary>
16         /// 主键ID
17         /// </summary>
18 
19         private int _id;
20         [FieldInfo(CanInsert = false, CanUpdate = false)]
21         public int ID
22         {
23             get { return _id; }
24             set { _id = value; }
25         }
26 
27         /// <summary>
28         /// 类别名
29         /// </summary>
30         private string _typename;
31 
32         public string TypeName
33         {
34             get { return _typename; }
35             set { _typename = value; }
36         }
37 
38         private string _ddate;
39 
40         public string dDate
41         {
42             get { return _ddate; }
43             set { _ddate = value; }
44         }
45 
46         private string _logcontent;
47 
48         public string logContent
49         {
50             get { return _logcontent; }
51             set { _logcontent = value; }
52         }
53 
54         private string _person;
55 
56         public string Person
57         {
58             get { return _person; }
59             set { _person = value; }
60         }
61 
62     }
63 }
View Code

 
如果直接复制上面代码到你类去会报错。找不到引用。QX.GYHelpers.dll 是我自己根据网上或项目中遇到整理出来封装的一个帮助类。

 信心的会发现类名上面有[TableInfo="数据库表名"],这就是前面提到为什么类名要和数据库表名一样。[FieldInfo(CanInsert = false, CanUpdate = false)] 会出现在ID上面。意思是 ID将不参与新增ID或这修改ID.

   下面新建项目。创建DAL层。在DAL层右键新建类Base.dal:

技术分享
  1 using QX.DBHelpers;
  2 using System;
  3 using System.Collections.Generic;
  4 using System.Linq;
  5 using System.Text;
  6 
  7 namespace Qx_SmkjItem.Dal
  8 {
  9     public class BaseDal<T> where T : class,new()
 10     {
 11         internal SqlServerDBHelper _dbh = null;
 12         public BaseDal()
 13         {
 14             string ConnStr = SystemConfig.GetConfigData("DataStr", string.Empty);
 15 
 16             _dbh = new SqlServerDBHelper(ConnStr);
 17         }
 18 
 19 
 20         /// <summary>
 21         /// 新增一个对象到数据库
 22         /// </summary>
 23         /// <param name="model">对象</param>
 24         /// <returns></returns>
 25         public string GetTableCount(string TableName)
 26         {
 27             string sql = "Select Count(*) From " + TableName;
 28 
 29             return _dbh.ExecuteScalar(sql).ToString();
 30         }
 31 
 32         /// <summary>
 33         /// 新增一个对象到数据库
 34         /// </summary>
 35         /// <param name="model">对象</param>
 36         /// <returns></returns>
 37         public bool Add(T model)
 38         {
 39             return _dbh.Insert<T>(model);
 40         }
 41 
 42         /// <summary>
 43         /// 根据主键值删除一条数据
 44         /// </summary>
 45         /// <param name="keyValue">主键值</param>
 46         /// <returns></returns>
 47         public virtual bool Delete(object keyValue)
 48         {
 49             return _dbh.Delete<T>(keyValue);
 50         }
 51 
 52         /// <summary>
 53         /// 根据主键值集合删除多条数据
 54         /// </summary>
 55         /// <param name="keyValue">主键值集合</param>
 56         /// <returns></returns>
 57         public bool Deletes(List<string> keyValueList)
 58         {
 59             _dbh.TransactionBegin();
 60             try
 61             {
 62                 if (keyValueList.Count > 0)
 63                 {
 64                     foreach (var keyValue in keyValueList)
 65                     {
 66                         if (_dbh.Delete<T>(keyValue) == false)
 67                         {
 68                             _dbh.TransactionRollBack();
 69                             return false;
 70                         }
 71                     }
 72                 }
 73             }
 74             catch (Exception)
 75             {
 76                 _dbh.TransactionRollBack();
 77                 throw;
 78             }
 79             _dbh.TransactionCommit();
 80             return true;
 81         }
 82 
 83         /// <summary>
 84         /// 更新一个实例数据
 85         /// </summary>
 86         /// <param name="model">实例</param>
 87         /// <returns></returns>
 88         public virtual bool Update(T model)
 89         {
 90             return _dbh.Update<T>(model);
 91         }
 92 
 93         /// <summary>
 94         /// 更新多个实例数据
 95         /// </summary>
 96         /// <param name="keyValue">实例集合</param>
 97         /// <returns></returns>
 98         public virtual bool Updates(List<T> modelList)
 99         {
100             _dbh.TransactionBegin();
101             try
102             {
103                 if (modelList.Count > 0)
104                 {
105                     foreach (var model in modelList)
106                     {
107                         if (_dbh.Update<T>(model) == false)
108                         {
109                             _dbh.TransactionRollBack();
110                             return false;
111                         }
112                     }
113                 }
114             }
115             catch (Exception)
116             {
117                 _dbh.TransactionRollBack();
118                 throw;
119             }
120             _dbh.TransactionCommit();
121             return true;
122         }
123 
124         /// <summary>
125         /// 获取所有数据
126         /// </summary>
127         /// <returns></returns>
128         public virtual List<T> GetAll()
129         {
130             return _dbh.GetBySQL<T>();
131         }
132 
133         /// <summary>
134         /// 获取所有数据
135         /// </summary>
136         /// <returns></returns>
137         public virtual List<T> GetAll(bool childData)
138         {
139             return _dbh.GetBySQL<T>(childData);
140         }
141 
142         /// <summary>
143         /// 根据where语句进行查询
144         /// </summary>
145         /// <param name="where">where条件</param>
146         /// <param name="parameters">parameter参数</param>
147         /// <returns></returns>
148         public List<T> GetBySQL(string where, params object[] parameters)
149         {
150             return _dbh.GetBySQL<T>(where, parameters);
151         }
152 
153         /// <summary>
154         /// 根据where语句进行查询
155         /// </summary>
156         /// <param name="where">where条件</param>
157         /// <param name="childData">是否获取子数据</param>
158         /// <param name="parameters">parameter参数</param>
159         /// <returns></returns>
160         public List<T> GetBySQL(string where, bool childData, params object[] parameters)
161         {
162             return _dbh.GetBySQL<T>(where, childData, parameters);
163         }
164 
165         /// <summary>
166         /// 分页查询方法
167         /// </summary>
168         /// <param name="pageSize">页大小</param>
169         /// <param name="pageIndex">页码</param>
170         /// <param name="rowCount">当前查询一共有多少数据</param>
171         /// <param name="sqlWhere">SQL WHERE 条件</param>
172         /// <returns></returns>
173         public List<T> GetPageBySQL(int pageSize, int pageIndex, out int rowCount, string sqlWhere)
174         {
175             return _dbh.GetPageBySQL<T>(pageSize, pageIndex, out rowCount, sqlWhere);
176         }
177     }
178 }
View Code

 Base.dal里面包含增删改查的dal。这里就不解释Base.dal的具体信息。代码有注释。 然后新建对应的Dal层。新建的dal层要继承base.dal,同时引用项目model层

技术分享
using Qx_SmkjItem.Model;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Qx_SmkjItem.Dal
{
  /// <summary>
 /// 日志信息DAL
 /// </summary>
  public  class log_InfoDal: BaseDal<log_Info>
    {
    }
}
View Code

  继承玩之后。新建项目,创建BLL层。在BLL层右键新建项目,创建对应的BLL层。引用Model DAL层

技术分享
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Newtonsoft.Json;
using Qx_SmkjItem.Dal;
using Qx_SmkjItem.Model;

namespace Qx_SmkjItem.BLL
{
 public   class log_InfoBll
    {
        log_InfoDal dal = new log_InfoDal();
        /// <summary>
        ///  所有数据条目数
        /// </summary>
        public string GetZJTypeCount()
        {
            return dal.GetTableCount("log_Info");

        }

        /// <summary>
        ///  新增条目
        /// </summary>
        public string Add(string lgoinfo)
        {
            log_Info Object = JsonConvert.DeserializeObject<log_Info>(lgoinfo);

            return JsonConvert.SerializeObject(dal.Add(Object));
        }

        /// <summary>
        ///  修改一条数据
        /// </summary>                        
        public string Update(string lgoinfo)
        {
            return JsonConvert.SerializeObject(dal.Update(JsonConvert.DeserializeObject<log_Info>(lgoinfo)));
        }

        /// <summary>
        ///  修改多条数据
        /// </summary>                           
        public string Updates(string lgoinfoList)
        {
            return JsonConvert.SerializeObject(dal.Updates(JsonConvert.DeserializeObject<List<log_Info>>(lgoinfoList)));
        }

        /// <summary>
        ///  删除一条数据
        /// </summary>                            
        public string Delete(string code)
        {
            return JsonConvert.SerializeObject(dal.Delete(code));
        }

        /// <summary>
        ///  删除多条数据
        /// </summary>        
        public string Deletes(string codeList)
        {
            return JsonConvert.SerializeObject(dal.Deletes(JsonConvert.DeserializeObject<List<string>>(codeList)));
        }

        /// <summary>
        ///  获取所有数据(不包含子集数据)
        /// </summary>
        public string GetAll()
        {
            return JsonConvert.SerializeObject(dal.GetAll());
        }

        /// <summary>
        ///  获取所有数据(包含子集数据)
        /// </summary>
        public string GetAllAndChild(string getChild)
        {
            return JsonConvert.SerializeObject(dal.GetAll(Convert.ToBoolean(getChild)));
        }

        /// <summary>
        ///  根据SqlWhere条件获取数据(不包含子集数据)
        /// </summary>  
        public string GetBySql(string sqlWhere)
        {
            return JsonConvert.SerializeObject(dal.GetBySQL(sqlWhere));
        }

        /// <summary>
        ///  根据SqlWhere条件获取数据(包含子集数据)
        /// </summary> 
        public string GetBySqlAndChild(string sqlWhere, string getChild)
        {
            return JsonConvert.SerializeObject(dal.GetBySQL(sqlWhere, Convert.ToBoolean(getChild)));
        }

        /// <summary>
        ///  根据SqlWhere条件分页 获取数据(不包含子集数据)
        /// </summary> 
        public string GetPageBySql(string pageSize, string pageIndex, string sqlWhere)
        {
            int outCount = 0;
            return JsonConvert.SerializeObject(dal.GetPageBySQL(Convert.ToInt32(pageSize), Convert.ToInt32(pageIndex), out outCount, sqlWhere));
        }
    }
}
View Code

  看完上面代码 你会大概知道这是在做什么。其中需要特别注意的是 BLL层的对象也就是model层对应model一定要正确。如果出现sql之类的错误提示。那么就要仔细检查三个层的对象是否对应。

    接下来就是用到实际的项目中,继续创建项目,创建windows窗体,设为启动项目。然后新建窗口。。

技术分享

 上面用的是Cskin 控件布局。在官网下载最新版的控件库 :http://www.cskin.net/  下载下来后 会有文档提示你如何用。一样的拖控件。窗体一般的继承的Form.

那么F7 进入代码 把Form 替换为 CCSkinMain

技术分享
using System;
using CCWin;
using Newtonsoft.Json;
using Qx_SmkjItem.BLL;
using Qx_SmkjItem.Model;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;


namespace test
{
    public partial class FrmLogInfo : CCSkinMain
    {
        public FrmLogInfo()
        {
            InitializeComponent();
        }
        log_typeBll sbll = new log_typeBll();
        log_Info st = new log_Info();
        log_InfoBll stb = new log_InfoBll();
        /// <summary>
        /// 获取类型数据绑定到下拉框
        /// </summary>
        private void GetTypes()
        {
            cmbtype.DisplayMember = "TypeName";
            cmbtype.ValueMember = "ID";
            cmbtype.DataSource = JsonConvert.DeserializeObject<List<log_type>>(sbll.GetAll());
        }

        #region 分页
        int rowcount = 0;
        int pagecount = 0;
        public int Inum = 1;
        public int pagesize = 10;
        #endregion
        /// <summary>
        /// 根据条件查询数据(除内容外)
        /// </summary>
        private void GetTypeInfo()
        {
           
            StringBuilder strSwhere = new StringBuilder();
            if (!string.IsNullOrEmpty(cmbtype.Text.Trim()))
            {
                strSwhere.Append("and TypeName =‘" + cmbtype.Text.Trim() + "");
            }
            if (!string.IsNullOrEmpty(dtdate.Text.Trim()))
            {
                strSwhere.Append("and dDate like ‘%" + dtdate.Text.Trim() + "%‘");
            }
            if (!string.IsNullOrEmpty(txtbz.Text.Trim()))
            {
                strSwhere.Append("and Person like ‘%" + txtbz.Text.Trim() + "%‘");
            }
            if (strSwhere.Length>0)
            {
                strSwhere.Remove(0, 3);
            }
            List<log_Info> loglist = JsonConvert.DeserializeObject<List<log_Info>>(stb.GetBySql(strSwhere.ToString()));
            rowcount = loglist.Count;
            pagecount = rowcount % pagesize;

            if (pagecount == 0)
            {
                pagecount = rowcount / pagesize;
            }
            else
            {
                pagecount = rowcount / pagesize + 1;
            }
            this.lblzys.Text = "" + pagecount.ToString() + "";
            this.lbldqys.Text = "当前" + Inum.ToString() + "";
           
            dgvdata.DataSource = JsonConvert.DeserializeObject<List<log_Info>>(stb.GetPageBySql(pagesize.ToString(), Inum.ToString()
                , strSwhere.ToString()));
        }
        /// <summary>
        /// 清空文本框数据
        /// </summary>
        private void Qktxt()
        {
            rbcontent.Text = string.Empty; txtbz.Text = string.Empty;
        }

        /// <summary>
        /// 查询
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btncx_Click(object sender, EventArgs e)
        {
            GetTypeInfo();
        }
        /// <summary>
        /// 删除
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void cmdelete_Click(object sender, EventArgs e)
        {
            int delecount = 0;
            for (int i = 0; i < dgvdata.SelectedRows.Count; i++)
            {
                if (Convert.ToBoolean(dgvdata.SelectedRows[i].Cells[0].Value) == true)
                {
                    int id = Convert.ToInt32(dgvdata.SelectedRows[i].Cells[0].Value);
                    string ss = stb.Delete(id.ToString());
                    if (ss == "true")
                    {
                        delecount++;
                    }
                }
            }
            MessageBox.Show("已删除成功当前信息" + delecount + "", "提示");
            GetTypeInfo();
        }
        /// <summary>
        /// 获取选中行数据
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void dgvdata_SelectionChanged(object sender, EventArgs e)
        {
            try
            {
                for (int i = 0; i < dgvdata.SelectedRows.Count; i++)
                {
                    cmbtype.Text = dgvdata.SelectedRows[i].Cells["TypeName"].Value.ToString();
                    rbcontent.Text = dgvdata.SelectedRows[i].Cells["logContent"].Value.ToString();
                    dtdate.Text = dgvdata.SelectedRows[i].Cells["dDate"].Value.ToString();
                    txtbz.Text = dgvdata.SelectedRows[i].Cells["Person"].Value.ToString();
                }
            }
            catch (Exception ex) { }
        }

        /// <summary>
        /// 首页
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void lkSy_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
        {
            Inum = 1;
            GetTypeInfo();
        }

        /// <summary>
        /// 上一页
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void lkSyy_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
        {
            if (Inum < 0 || Inum == 1)
            {
                MessageBox.Show("已是首页", "提示");
            }
            else
            {
                Inum--;
                GetTypeInfo();
            }
        }

        /// <summary>
        /// 下一页
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void lkxyy_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
        {
            Inum++;
            if (Inum > pagecount)
            {
                MessageBox.Show("已是最后一页", "提示");
            }
            else
            {
                GetTypeInfo();
            }
        }

        /// <summary>
        /// 尾页
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void lkwy_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
        {
            Inum = pagecount;
            GetTypeInfo();
        }

        private void FrmLogInfo_Load(object sender, EventArgs e)
        {
         
        }
        /// <summary>
        /// 导出Excel方法
        /// </summary>
        /// <param name="fileName"></param>
        /// <param name="myDGV"></param>
        private void ExportExcel(string fileName, DataGridView myDGV)
        {
            string saveFileName = "";
            SaveFileDialog saveDialog = new SaveFileDialog();
            saveDialog.DefaultExt = "xls";
            saveDialog.Filter = "Excel文件|*.xls";
            saveDialog.FileName = fileName;
            saveDialog.ShowDialog();
            saveFileName = saveDialog.FileName;
            if (saveFileName.IndexOf(":") < 0)
                return; //被点了取消   
            Microsoft.Office.Interop.Excel.Application xlApp = new Microsoft.Office.Interop.Excel.Application();
            if (xlApp == null)
            {
                MessageBox.Show("无法创建Excel对象,可能您的机子未安装Excel", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }
            Microsoft.Office.Interop.Excel.Workbooks workbooks = xlApp.Workbooks;
            Microsoft.Office.Interop.Excel.Workbook workbook = workbooks.Add(Microsoft.Office.Interop.Excel.XlWBATemplate.xlWBATWorksheet);
            Microsoft.Office.Interop.Excel.Worksheet worksheet = (Microsoft.Office.Interop.Excel.Worksheet)workbook.Worksheets[1];//取得sheet1  
            string[] array = new string[myDGV.Columns.Count];
            //获取Visble =true 的列   
            foreach (DataGridViewColumn column in myDGV.Columns)
            {
                if (column.Visible == true)
                {
                    array[column.DisplayIndex] = column.HeaderText + | + column.Name; ;
                }
            }
            int RowsCount = myDGV.Rows.Count;
            int ColumnsCount = array.Length;
            int mm = 1;
            for (int i = 0; i < ColumnsCount; i++)
            {
                string[] str = new string[2];
                string ColumnName;
                try
                {
                    str = array.GetValue(i).ToString().Split(|);
                    ColumnName = str[0];
                }
                catch
                {
                    continue;
                }
                //导出列名   
                worksheet.Cells[1, mm] = ColumnName;
                //导出列内容   
                for (int m = 0; m < RowsCount; m++)
                {
                    try
                    {
                        worksheet.Cells[m + 2, mm] = "" + myDGV.Rows[m].Cells[str[1]].FormattedValue.ToString();
                    }
                    catch
                    { }
                }
                //执行完一列 mm++   
                mm++;
            }
            worksheet.Columns.EntireColumn.AutoFit();

            if (saveFileName != "")
            {
                try
                {
                    workbook.Saved = true;
                    workbook.SaveCopyAs(saveFileName);
                }
                catch (Exception ex)
                {
                    MessageBox.Show("导出文件时出错,文件可能正被打开!\\n" + ex.Message, "警告", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                }
            }
            xlApp.Quit();
            GC.Collect();//强行销毁   
            MessageBox.Show(fileName + "的表格资料保存成功", "提示");
        }
        /// <summary>
        /// 导出
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnDc_Click(object sender, EventArgs e)
        {
            if (dgvdata.Rows.Count > 0)
            {
                ExportExcel(DateTime.Now.ToShortDateString() + "日志报告", dgvdata);

            }
            else
            {
                
                MessageBox.Show("没有数据可导出,请先查询数据!", "警告", MessageBoxButtons.OK, MessageBoxIcon.Warning);
            }
        }
    }
}
View Code

   上面代码个人觉得已经很详细了。查询 删除 分页 导出都有。只是缺少新增和修改。由于我列出的是操作日志信息。所以就没有修改和新增。不过下面代码会给出

技术分享
 /// <summary>
        /// 添加
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnAdd_Click(object sender, EventArgs e)
        {
            sy.TypeName = txttype.Text.Trim();
            string iss = sbll.Add(JsonConvert.SerializeObject(sy));
            if (iss == "true")
            {
            }
            GetsmTypeInfo();
        }
        /// <summary>
        /// 修改
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnupdate_Click(object sender, EventArgs e)
        {
            for (int i = 0; i < dgvdata.SelectedRows.Count; i++)
            {
                sy.ID = Convert.ToInt32(dgvdata.SelectedRows[i].Cells["ID"].Value);
                sy.TypeName = txttype.Text.Trim();
                string iss = sbll.Update(JsonConvert.SerializeObject(sy));
                if (iss == "true")
                {
                }
            }
            GetsmTypeInfo();
            txttype.Text = string.Empty;
        }
View Code

   以上就是 winform的三层架构的简单增删改查。 由于代码简单。所以这是给才开始学的一个参考。有些代码没有优化 和存在一些bug。但不影响正常使用。老手们看到给出你们的意见。便于小弟及时修正。。。请赐教。

 

 

 

 

 

    

 



以上是关于C# Winform 三层架构的主要内容,如果未能解决你的问题,请参考以下文章

C# Dapper基本三层架构使用 (Web UI层)

基于C#+SQL Server2008 开发三层架构(WinForm)图书管理系统100010014

基于接口(工厂模式)三层架构的 winform 权限控制 初学winform程序,希望高手指点下。

Winform入门见解

C#winform中在DataGridView里批量(增,删,改)怎么实现?(要使用3层架构).急啊````

C#三层架构