Winform入门见解
winform算是C#比较快速的入门的一个了,简单的控件拖拽然后写上每个控件对应的事件。然后就可以了。需要美观的点 可以用Skin皮肤就完成了。我们先不说复杂的,就来个普通的三层架构来增删改查 分页和导出。
环境 Vs2017+sql server2008r2 框架4.0
首先创建新的解决方案输入你的名字。然后在解决方案右键选择添加新项目,添加类库。这里就不用图示来演示如何创建了。先建立Model层。三层架构我也不用说了,不会的可以百度。Model层创建完后,新建类。类名和你的数据库表名一样。数据库字段对应的就是类的属性。
using QX.DBHelpers.Attributes;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text; namespace Qx_SmkjItem.Model
{
/// <summary>
/// 日志信息
/// </summary>
[TableInfo(Name = "log_Info")]
public class log_Info
{
/// <summary>
/// 主键ID
/// </summary> private int _id;
[FieldInfo(CanInsert = false, CanUpdate = false)]
public int ID
{
get { return _id; }
set { _id = value; }
} /// <summary>
/// 类别名
/// </summary>
private string _typename; public string TypeName
{
get { return _typename; }
set { _typename = value; }
} private string _ddate; public string dDate
{
get { return _ddate; }
set { _ddate = value; }
} private string _logcontent; public string logContent
{
get { return _logcontent; }
set { _logcontent = value; }
} private string _person; public string Person
{
get { return _person; }
set { _person = value; }
} }
}
如果直接复制上面代码到你类去会报错。找不到引用。QX.GYHelpers.dll 是我自己根据网上或项目中遇到整理出来封装的一个帮助类。
信心的会发现类名上面有[TableInfo="数据库表名"],这就是前面提到为什么类名要和数据库表名一样。[FieldInfo(CanInsert = false, CanUpdate = false)] 会出现在ID上面。意思是 ID将不参与新增ID或这修改ID.
下面新建项目。创建DAL层。在DAL层右键新建类Base.dal:
using QX.DBHelpers;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text; namespace Qx_SmkjItem.Dal
{
public class BaseDal<T> where T : class,new()
{
internal SqlServerDBHelper _dbh = null;
public BaseDal()
{
string ConnStr = SystemConfig.GetConfigData("DataStr", string.Empty); _dbh = new SqlServerDBHelper(ConnStr);
} /// <summary>
/// 新增一个对象到数据库
/// </summary>
/// <param name="model">对象</param>
/// <returns></returns>
public string GetTableCount(string TableName)
{
string sql = "Select Count(*) From " + TableName; return _dbh.ExecuteScalar(sql).ToString();
} /// <summary>
/// 新增一个对象到数据库
/// </summary>
/// <param name="model">对象</param>
/// <returns></returns>
public bool Add(T model)
{
return _dbh.Insert<T>(model);
} /// <summary>
/// 根据主键值删除一条数据
/// </summary>
/// <param name="keyValue">主键值</param>
/// <returns></returns>
public virtual bool Delete(object keyValue)
{
return _dbh.Delete<T>(keyValue);
} /// <summary>
/// 根据主键值集合删除多条数据
/// </summary>
/// <param name="keyValue">主键值集合</param>
/// <returns></returns>
public bool Deletes(List<string> keyValueList)
{
_dbh.TransactionBegin();
try
{
if (keyValueList.Count > )
{
foreach (var keyValue in keyValueList)
{
if (_dbh.Delete<T>(keyValue) == false)
{
_dbh.TransactionRollBack();
return false;
}
}
}
}
catch (Exception)
{
_dbh.TransactionRollBack();
throw;
}
_dbh.TransactionCommit();
return true;
} /// <summary>
/// 更新一个实例数据
/// </summary>
/// <param name="model">实例</param>
/// <returns></returns>
public virtual bool Update(T model)
{
return _dbh.Update<T>(model);
} /// <summary>
/// 更新多个实例数据
/// </summary>
/// <param name="keyValue">实例集合</param>
/// <returns></returns>
public virtual bool Updates(List<T> modelList)
{
_dbh.TransactionBegin();
try
{
if (modelList.Count > )
{
foreach (var model in modelList)
{
if (_dbh.Update<T>(model) == false)
{
_dbh.TransactionRollBack();
return false;
}
}
}
}
catch (Exception)
{
_dbh.TransactionRollBack();
throw;
}
_dbh.TransactionCommit();
return true;
} /// <summary>
/// 获取所有数据
/// </summary>
/// <returns></returns>
public virtual List<T> GetAll()
{
return _dbh.GetBySQL<T>();
} /// <summary>
/// 获取所有数据
/// </summary>
/// <returns></returns>
public virtual List<T> GetAll(bool childData)
{
return _dbh.GetBySQL<T>(childData);
} /// <summary>
/// 根据where语句进行查询
/// </summary>
/// <param name="where">where条件</param>
/// <param name="parameters">parameter参数</param>
/// <returns></returns>
public List<T> GetBySQL(string where, params object[] parameters)
{
return _dbh.GetBySQL<T>(where, parameters);
} /// <summary>
/// 根据where语句进行查询
/// </summary>
/// <param name="where">where条件</param>
/// <param name="childData">是否获取子数据</param>
/// <param name="parameters">parameter参数</param>
/// <returns></returns>
public List<T> GetBySQL(string where, bool childData, params object[] parameters)
{
return _dbh.GetBySQL<T>(where, childData, parameters);
} /// <summary>
/// 分页查询方法
/// </summary>
/// <param name="pageSize">页大小</param>
/// <param name="pageIndex">页码</param>
/// <param name="rowCount">当前查询一共有多少数据</param>
/// <param name="sqlWhere">SQL WHERE 条件</param>
/// <returns></returns>
public List<T> GetPageBySQL(int pageSize, int pageIndex, out int rowCount, string sqlWhere)
{
return _dbh.GetPageBySQL<T>(pageSize, pageIndex, out rowCount, sqlWhere);
}
}
}
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 = ;
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 = ;
int pagecount = ;
public int Inum = ;
public int pagesize = ;
#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>)
{
strSwhere.Remove(, );
}
List<log_Info> loglist = JsonConvert.DeserializeObject<List<log_Info>>(stb.GetBySql(strSwhere.ToString()));
rowcount = loglist.Count;
pagecount = rowcount % pagesize; if (pagecount == )
{
pagecount = rowcount / pagesize;
}
else
{
pagecount = rowcount / pagesize + ;
}
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 = ;
for (int i = ; i < dgvdata.SelectedRows.Count; i++)
{
if (Convert.ToBoolean(dgvdata.SelectedRows[i].Cells[].Value) == true)
{
int id = Convert.ToInt32(dgvdata.SelectedRows[i].Cells[].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 = ; 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 = ;
GetTypeInfo();
} /// <summary>
/// 上一页
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void lkSyy_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
{
if (Inum < || Inum == )
{
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(":") < )
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[];//取得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 = ;
for (int i = ; i < ColumnsCount; i++)
{
string[] str = new string[];
string ColumnName;
try
{
str = array.GetValue(i).ToString().Split('|');
ColumnName = str[];
}
catch
{
continue;
}
//导出列名
worksheet.Cells[, mm] = ColumnName;
//导出列内容
for (int m = ; m < RowsCount; m++)
{
try
{
worksheet.Cells[m + , mm] = "'" + myDGV.Rows[m].Cells[str[]].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 > )
{
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 = ; 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。但不影响正常使用。老手们看到给出你们的意见。便于小弟及时修正。。。请赐教。
Winform入门见解的更多相关文章
- 8、面向对象以及winform的简单运用(事件与winform入门)
事件 Visual studio中对可视化窗体控件的事件处理机理: 所有的.NET Framework可视化窗体控件的预定义事件,都会某一对应的“事件名+Handler”委托类型的变量.与此事件相关的 ...
- winForm入门学习
Windows窗体 属性: name:对象的名称 windowsState:初始化窗体的大小,Normal,Minimized,Maximized StartPosition:窗体起始位置,Manua ...
- 16Aspx.com源码2014年7月详细
Web电子商务网(三层)V2.0源码 2014-07-31 [VS2010] 源码介绍: Web电子商务网(三层)V2.0源码 源码描述: 一.源码特点 采用三层架构开发, ...
- WCF入门及在WinForm中动态调用
一.WCF入门 1. 新建立空白解决方案,并在解决方案中新建项目,项目类型为:WCF服务应用程序,删除系统生成的两个文件IService1.cs与Service1.svc, 添加自定义的WCF[服务文 ...
- c#Winform程序调用app.config文件配置数据库连接字符串 SQL Server文章目录 浅谈SQL Server中统计对于查询的影响 有关索引的DMV SQL Server中的执行引擎入门 【译】表变量和临时表的比较 对于表列数据类型选择的一点思考 SQL Server复制入门(一)----复制简介 操作系统中的进程与线程
c#Winform程序调用app.config文件配置数据库连接字符串 你新建winform项目的时候,会有一个app.config的配置文件,写在里面的<connectionStrings n ...
- .Net 桌面程序(winform,wpf,跨平台avalonia)打安装包部署到windows 入门
.Net 桌面程序(winform,wpf,跨平台avalonia)部署到windows 入门 本文以为avalonia为例,用Setup Factory 将.Net桌面程序(winform,wpf, ...
- Winform 控件的入门级使用(一)
开始总结一下控件的基本用法,方便以后查阅. 一.Label Label 的使用频率很高,基本上也没有什么难度. #region Winform //label label.Text = "这 ...
- Winform & Devexpress Chart使用入门
一.Chart(Winform) 使用图表控件(chart)首先要理解图表区域(ChartArea).XY轴(AxisX.AxisY).数据点(Series).标题(Title).图例(Legend) ...
- stm32入门学习路线个人见解
可以说就目前的市场需求来看,stm32在单片机领域已经拥有了绝对的地位,51什么的已经过时了也只能拿来打基础了,最后依然会转到stm32来,也正是因为这样stm32的学习者越来越多,其中不难发现绝大部 ...
随机推荐
- Xmem
http://blog.csdn.net/jthink_/article/details/43302615
- [Vue] Use Vue.js Component Computed Properties
You can add computed properties to a component to calculate a property on the fly. The benefit of th ...
- dbvisualizer 使用笔记
快捷键:CTRL+SHIFT+F 格式化选中的sql语句 导入导出数据操作 导入: 1.将Exel文件另存为csv文件 2.在dbvisualizer中点击开发数据库,如test_dev,然后在te ...
- Birt
http://www.eclipse.org/birt/ 咖啡图 http://www.kafeitu.me/activiti/2012/05/26/kft-activiti-demo.html
- [TypeScript] Create a fluent API using TypeScript classes
You can create an easy to chain API using TypeScript classes. Learn about the thisreturn type annota ...
- Android-通过Java代码来实现属性动画
Android-通过Java代码来实现属性动画 除了能够使用定义xml文件来设置动画之外.还能够使用java代码来进行控制动画. 示比例如以下: 布局文件: <RelativeLayout xm ...
- js进阶 11-1 jquery中的页面内容操作的三个方法
jquery中的页面内容操作的三个方法 一.总结 一句话总结:记三个方法即可.text,html,val.因为这里是方法,所以设置值的是后面方法的参数. 1.jquery中的页面内容操作的三个方法? ...
- js如何操作表格(常用属性方法汇总)
js如何操作表格(常用属性方法汇总) 一.总结 一句话总结: 二.表格相关的属性和方法 1.1 Table 对象集合 cells[] 返回包含表格中所有单元格的一个数组. 语法:tableObject ...
- 常用Java开发工具类
common: LruLinkedHashMap:一个支持Lru算法的LinkedHashMap. 源码地址:点击打开链接 MD5:MD5工具类 源码地址:点击打开链接 Slicer:可以将List切 ...
- 西方教育骗局,终于明白精英和普通人的残酷差别!(该校流传着一个数字——4。即“4小时睡眠、4杯咖啡、GPA4.0”——要想获得满分为4分的成绩,每天只睡4个小时,困了就喝4大杯咖啡)
2018-02-14 00:00英国/私立学校 你不知道的是:西方教育通过一个宽松的过程,偷偷完成了社会分层. 1 “中国学生真是太苦了!”我的同学李女士总是发出这样的感慨. 李女士是我中学同学,在一 ...