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。但不影响正常使用。老手们看到给出你们的意见。便于小弟及时修正。。。请赐教。