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 }
如果直接复制上面代码到你类去会报错。找不到引用。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 }
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> { } }
继承玩之后。新建项目,创建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)); } } }
看完上面代码 你会大概知道这是在做什么。其中需要特别注意的是 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); } } } }
上面代码个人觉得已经很详细了。查询 删除 分页 导出都有。只是缺少新增和修改。由于我列出的是操作日志信息。所以就没有修改和新增。不过下面代码会给出
/// <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; }
以上就是 winform的三层架构的简单增删改查。 由于代码简单。所以这是给才开始学的一个参考。有些代码没有优化 和存在一些bug。但不影响正常使用。老手们看到给出你们的意见。便于小弟及时修正。。。请赐教。
以上是关于C# Winform 三层架构的主要内容,如果未能解决你的问题,请参考以下文章
基于C#+SQL Server2008 开发三层架构(WinForm)图书管理系统100010014
基于接口(工厂模式)三层架构的 winform 权限控制 初学winform程序,希望高手指点下。