C#项目知识点
1.相关术语:
呼叫中心(Call Center) 。公司客服系统,接警平台,医院接诊系统
计算机与电信集成技术(CTI)
CRM(客户关系管理, Customer Relationship Management )。CRM不一定非要和CTI集成。和CTI集成以后就有了自动化的过程。
OA(Office Automation);MIS(Management Information System,什么都是MIS系统);
ERP(Enterprise Resources Planning)。
2.显示窗口的两种方式:
非模态(Modaless):Show
模态(Modal),阻塞主窗口:ShowDialog() 只有当阻塞窗体关闭时,才会执行下面的语句。
相当于C#中的 ReadLine ReadKey,只有当用户继续的时候,才能继续操作。
3.全局变量
第一步:
用一个类专门保存全局变量 static
//保留全局变量的ID
class Gls
{
//保留全局变量的ID
public static int ID;
}
第二步:在用到全局变量的地方用全局变量进行接收。
Gls.ID = logmod.Id;
第三步:
//tboldpwd.Text =Gls.ID.ToString();
//MessageBox.Show(tboldpwd.Text.Trim());
4.如何进行两个窗体之间的调用,即窗体2读取窗体1中的某个控件的值
(1)由于窗体2中声明控件的字段都是私有的,private,那么需要把该控件声明为public ,公有的属性,
那样的话,窗体1即可调用窗体2的属性。
窗体1:
//我要调用窗体2里的值
Form2 f2 = new Form2();
f2.Show();
MessageBox.Show(f2.Name2);
窗体2:★★需要声明该控件为public
public string Name2
{
get
{
return textBox1.Text.Trim();
}
}
相当于先声明一个外面的类,然后调用外面类得public属性,在外面类得public属性;里进行调用。
(2).窗体2的值要输出在窗体1中。★★★★★
第一步:在窗体2中声明一个窗体1的对象
public Form1 f1 ★★窗体2中进行声明窗体1的对象
{
get;
set;
}
第二步:在窗体1中声明属性
public string f1 ★★窗体1中进行声明一个属性
{
set
{
this.textBox1.Text = value;
}
get
{
return this.textBox1.Text;
}
}
第三步:窗体2中用声明的窗体1的对象来调用窗体1中声明的属性。
f1.f1 = "hellow"; ★★窗体2声明的对象来调用窗体1中的属性
第四步:在窗体1中打开窗体2之前,让窗体2指向进行声明的窗体1对象
Form2 f2 = new Form2(); ★★窗体1中声明的外窗体指向外窗体声明的对象。
f2.f1 = this;
f2.Show();
5.如何使调用其他窗体的某个控件
(1)最快的方法是把该窗体的私有private字段改为publi,这样才能被其它窗体进行访问。
6.如何进行多条件查询。
(1)用1=1进行全表查询 ★★字符串拼接函数StringBuilder进行拼接
StringBuilder sb = new StringBuilder();
//sb.AppendLine("select * from table where 1=1");
sb.AppendLine("select * from table where ");
if (checkBox1.Checked)
{
sb.AppendLine("姓名 like @name");
}
if (checkBox2.Checked)
{
sb.AppendLine("and 年龄 =@年龄");
}
if (checkBox3.Checked)
{
sb.AppendLine("and 出生日期=@出生日期");
}
if (checkBox4.Checked)
{
sb.AppendLine("and 性别=@性别");
}
MessageBox.Show(sb.ToString());
(2)用范型的方法进行查询 把范型里面的东西当做数组的形式,给string.join进行拼接
List<string> list1 = new List<string>();
if (checkBox1.Checked)
{
list1.Add("姓名 like @name");
}
if (checkBox2.Checked)
{
list1.Add("年龄 =@年龄");
}
if (checkBox3.Checked)
{
list1.Add("出生日期=@出生日期");
}
if (checkBox4.Checked)
{
list1.Add("性别=@性别");
}
string s = string.Join(" and ", list1.ToArray());//如果数组中只有一个数,不执行拼接前的"and",只有当数组为两个的时候才能进行拼接,and进行连接。
MessageBox.Show("select * from table where "+s);
(3)多条件且或进行查询
List<string> list1 = new List<string>();
if (checkBox1.Checked)
{
list1.Add("姓名 like @name");
}
if (checkBox2.Checked)
{
list1.Add("年龄 =@年龄");
}
if (checkBox3.Checked)
{
list1.Add("出生日期=@出生日期");
}
if (checkBox4.Checked)
{
list1.Add("性别=@性别");
}
//这样的话,我只要判断下选择哪个单选按钮,即可进行拼接方式
string s = "";
if (rb1.Checked)
{
s = string.Join("and", list1.ToArray());
}
if (rb2.Checked)
{
s = string.Join("or", list1.ToArray());
}
MessageBox.Show("select * from table where " + s);
(4)多种条件同时进行查询
1)先声明公共变量
public string s = "";
public int tj = 0;
2)根据条件数量进行添加
s=cbselyj.Text + cbsellx.Text + tbselval.Text;
if (tj >0)
{
tbdiswb.Text +=cborand.Text+ s;
}
else
{
tbdiswb.Text += s;
}
tj++;
7.如何操作Excel
1).程序中新建一个文件夹,把NPOI的所有引用,都添加到新建的文件夹中,然后再从程序中进行添加引用,导入NPOI的命名空间。
using NPOI.HSSF.UserModel;
2).要想获取EXCEL里的信息,首先需要打开指定文件夹下的指定EXCEL文件
★★首先需要using IO空间
using System.IO;
FileStream stream = new FileStream(@"d:\cust.xls", FileMode.Open, FileAccess.Read);\
3).打开了指定的EXCEL文件后,系统依次对工作薄,工作表,行记录,列字段进行访问。
//获取工作薄
HSSFWorkbook workbook = new HSSFWorkbook(stream);
//获取第一张表
HSSFSheet sheet = workbook.GetSheetAt(0);
//获取行
HSSFRow row = sheet.GetRow(0);
//获取列
HSSFCell cell = row.GetCell(0);
★★要想获工作表,那么 工作表.GetSheet ,下面依次进行 对象.Get...
4).★★几种类型,字符类型(StringCellValue),数值类型用doule进行接收()
//字符类型
string value = row.GetCell(0).StringCellValue;
MessageBox.Show(value);
//数值类型(double NumericCellValue)
double num = row.GetCell(9).NumericCellValue;
MessageBox.Show(num.ToString());
//日期类型(DateTime,DateCellValue)
DateTime value2 = row.GetCell(10).DateCellValue;
MessageBox.Show(value2.ToString());
5).如何添加数据到EXCEL里
首先创建一个工作薄,然后创建一个工作表,在创建行,在指定的列,指定的类型里添,设置值为:HSSFWorkbook workbook = new HSSFWorkbook();
HSSFSheet sheet = workbook.CreateSheet();
HSSFRow rowd = sheet.CreateRow(4);
rowd.CreateCell(0, HSSFCell.CELL_TYPE_STRING).SetCellValue(textBox1.Text.Trim());
★★最后写入指定的文件里
using(FileStream stream = new FileStream(@"d:\cust.xls", FileMode.OpenOrCreate, FileAccess.ReadWrite))
{
workbook.Write(stream);
}
8.如何进行文件上传和下载操作
(1)文件的下载,首先要引用 FTP这个类名文件
FTP.FtpClient ftp = new FtpClient("127.0.0.1", "dmh", "123456");
ftp.Download("服务器的使用.xls", @"c:\123\服务器的使用.xls");
(2)文件的上传
FtpClient ftp = new FtpClient("127.0.0.1", "dmh", "123456");
ftp.Upload(new FileInfo(s), "0099.xls"); //类型是FileInfo,所以需要实例化下,先把Upload转到定义,进行查看
(3)★★★对文件进行保护★★★ 文件的上传
第一步:先获得文件的路径,然后把文件的路径给文件Md5进行加密
string filemd5 = MD5Value(textBox1.Text);
第二步:计算出文件的Md5值,然后再进一步进行内容加密,加上私钥
string newfilemd5 = GetMD5(filemd5 + "传智播客");
第三步:把加密好的密钥存放在文本文件中
File.WriteAllText(@"c:\101.txt", newfilemd5);
第四步:把原始文件和存放MD5的文本文件一起放到服务器中
FtpClient ftp = new FtpClient("127.0.0.1", "dmh", "123456");
ftp.Upload(new FileInfo(textBox1.Text), "0099.xls");
ftp.Upload(new FileInfo(@"c:\101.txt"), "0099.txt");
★★★文件的下载★★★
第一步:下载好两个文件
FTP.FtpClient ftp = new FtpClient("127.0.0.1", "dmh", "123456");
ftp.Download("0099.xls", @"c:\123\0099.xls");
ftp.Download("0099.txt", @"c:\123\0099.txt");
第二步:对原始文件进行文件加密(加密方法同上)
第三步:读出存放MD5的文本文件中的内容
string txtpwd = File.ReadAllText(@"c:\123\0099.txt");
第四步:如果文本文件中的MD5值不等于你进行加密的MD5值,说明文件本篡改了。
9.如何进行节点,进行无限分类
(1)如何添加节点 ★★★实例化一个对象,在上一级节点下进行添加
//每个节点就相当于一个对象,new来实例化
TreeNode nodeChin = new TreeNode();
//这个对象的文本
nodeChin.Text = "中国";
//放到指定树下,其根节点是你实例化了的对象
//treeView1.Nodes 是树的根
treeView1.Nodes.Add(nodeChin);
//在中国节点下添加一个节点广东
TreeNode nodeguangdong = new TreeNode();
nodeguangdong.Text = "广东";
nodeChin.Nodes.Add(nodeguangdong);
//在广东的节点下添加一个节点佛山
TreeNode nodefoshan = new TreeNode();
nodefoshan.Text = "佛山";
nodeguangdong.Nodes.Add(nodefoshan);
(2)我如何知道选择了哪一个节点呢?AfterSelect事件
有一个treeView1_AfterSelect
MessageBox.Show(e.Node.Text); 当前节点的文本。
(3)如何对所有的节点进行遍历呢?
第一步:我先对所有的根节点进行遍历
foreach (TreeNode node in treeView1.Nodes)
{
display(node);
}
void display(TreeNode node)
{
textBox1.AppendText(node.Text);
}
第二步:假设根节点下面还有节点的话,即Node.nodes.count>0的话,那么我在对跟节点进行遍历
if (node.Nodes.Count > 0)
{
foreach (TreeNode chilnode in node.Nodes)//在跟节点下
{
display(chilnode);
}
}
++++++++++++++++++++++++++++++++++++++++++++++++++++++++
void display(TreeNode node)
{
textBox1.AppendText(node.Text);
if (node.Nodes.Count > 0)
{
foreach (TreeNode chilnode in node.Nodes)//在跟节点下
{
display(chilnode);
}
}
}
++++++++++++++++++++++++++++++++++++++++++++++++++++++++
对数据库中的进行节点遍历
(2).进行无限分类
1)得出第一级节点
assort.BLL.assortBLL asbll = new assort.BLL.assortBLL();
//第一级节点
IEnumerable<assort.Model.assort> assmod = asbll.getid(0);
foreach (assort.Model.assort assmod1 in assmod)
{
TreeNode treenode = new TreeNode();
treenode.Text = assmod1.Name;
treeView1.Nodes.Add(treenode); //在树的根节点进行添加
display(treenode,(int)assmod1.ID);//这个地方传递的是节点和父类的id号,即是子类的sired
}
2)接收父节点的id号,然实例化一个节点对象,再进行递归调用。
//要往那颗树下进行添加子节点,父节点的id号
private void display(TreeNode node, int ID)
{
assort.BLL.assortBLL asbll = new assort.BLL.assortBLL();
//第一级节点
IEnumerable<assort.Model.assort> assmod = asbll.getid(ID);//把id号传过去
★★子节点再进行一次遍历。★★
foreach (assort.Model.assort assmod1 in assmod)
{
TreeNode treenode = new TreeNode();
treenode.Text = assmod1.Name;
node.Nodes.Add(treenode); //传过来的父节点下进行添加
display(treenode, (int)assmod1.ID);//这个地方传递的是当前节点和当前id号
}
}
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
节点的增删改查
10.如何进行拼音查询
//是否是同音字
bool ishom = ChineseChar.IsHomophone('稿', '高');
MessageBox.Show(ishom.ToString());
//识别是否是汉字字符
bool f = ChineseChar.IsValidChar('-');
MessageBox.Show(f.ToString());
//获取给定的所有同音字
//char[] chs = ChineseChar.GetChars("yang1"); //后面加上声调
//foreach (char ch1 in chs)
//{
// MessageBox.Show(Convert.ToString(ch1));
//}
////输出拼音
//ChineseChar cc = new ChineseChar('张');
//for (int i = 0; i < cc.PinyinCount; i++)
//{
// string s = cc.Pinyins[i];
// MessageBox.Show(s);
//}
//输出字符的首个音符
ChineseChar cc1 = new ChineseChar('龙');
string s1 = cc1.Pinyins[0];
MessageBox.Show(s1);
11.如何对DGV进行操作
(1)单元格获取的方法
VB.net的单元格获取的方法是 Me.DataGridView1.Item(0, bh)
C#单元格获取的方法是: dataGridView1.Rows[bh].Cells[0]; 行,列区分开来。
(2)一些常用的属性。
单元格行的改变
RowsDefaultCellStyle 行的默认样式
AlternatingRowsDefaultCellStyle 奇数行的默认样式
单元格的自动调整 AutoResizeRows 所有行的高度
DataGridView1.AutoResizeRows()
行标题的单元格样式
Me.DataGridView1.RowHeadersBorderStyle = DataGridViewHeaderBorderStyle.Sunken
列标题的单元格样式
Me.DataGridView1.ColumnHeadersBorderStyle = DataGridViewHeaderBorderStyle.Single
改变字段标头名称
DataGridView1.Columns(0).HeaderText = "使用者编号"
SortMode 排序模式
SelectionMode
FullColumnSelect 按列的模式整体选择
FullRowSelect 按行的模式整体选择
RowHeaderSelect 单击字段进行选中
设定UserID字段不可排序
Me.DataGridView1.Columns("UserID").SortMode = DataGridViewColumnSortMode.NotSortable
防止在DataGridView控制项中新增和删除数据列
DataGridView1.AllowUserToAddRows = False
DataGridView1.AllowUserToDeleteRows = False
12.如何保存文本框上一次输入的值
(1).找到Winform窗体中的Properties
(2).在Properties里面找到Settings.settings,选择你要保留的名称,类型。
(3).选中Winform中的控件,找到属性ApplicationSetting,在文本中Text选择你保留的名称。
(4).通过事件:执行
Settings.Default.Save();
(5).如果想要输出上一次保留的文本信息,
MessageBox.Show(Settings.Default.用户名);
13.全局变量
1.一个类专门保存全局变量 static
//保留全局变量的ID
class Gls
{
//保留全局变量的ID
public static int ID;
}
Gls.ID = logmod.Id;
14.DonNet用户控件继承UserControl类
15.避免重复打开多个子窗体
第一种方法:
(1)声明一个私有的private的子窗体对象
private logfrm logfrm1; //声明一个私有的logfrm窗体对象logfrm1
(2)在打开之前进行判断,如果子窗体没有打开或被释放了,则重新进行打开。
if (logfrm1 == null || logfrm1.IsDisposed)
{
logfrm1 = new logfrm();
logfrm1.MdiParent = this;
logfrm1.Show();
}
(3)如果子窗体已经存在,则给予焦点,并且置顶。
第二种方法 对所有的子窗体进行判断,如果子窗体是要打开的窗体,就退出程序,否则在循环结束时打开子窗体
foreach (Form childfrm in this.MdiChildren)
{
if (childfrm is logfrm)
{
childfrm.Activate();
return;
}
}
logfrm logfrm1 = new logfrm();
logfrm1.MdiParent = this;
logfrm1.Show();
第三种方法,稍微复杂些
userfrm userfrm1 = new userfrm();
foreach (Form childfrm in this.MdiChildren)
{ //判断子窗体是否为空
if (childfrm == null)
{
return;
}
//如果子窗体不为空的话
if (childfrm != null)
{ //判断子窗体是否是否是当前要打开的子窗体
if (childfrm is userfrm)
{
childfrm.Activate();
return;
}
//如果不是当前要打开的子窗体的话
else
{ //关闭子窗体
childfrm.Close();
//打开要打开的窗体
userfrm1.MdiParent = this;
userfrm1.Show();
userfrm1.Top = 0;
userfrm1.Left = 0;
return;
}
}
}
userfrm1.MdiParent = this;
userfrm1.Show();
userfrm1.Top = 0;
userfrm1.Left = 0;
★★★★★★上面的方法虽然好,但是代码过于复杂,更为简单的方法是在要打开的子窗体的方法前面进行对象的声明,这样就可以避免重复打开子窗体了。