多窗口切换
【功能目标】
1、实现多窗口切换(Panel)
2、动态生成窗口内文本框以及标签(重点)
3、改变文本框内容
【效果图】
【代码详解】
1、多窗口切换
如要实现多窗口切换,需要用到Panel,对于这个控件不熟悉的可以看我上一篇介绍;
Panel是容器控件,我们需要把这些页面的控件分别放入四个容器中,每个容器开始都设计为不显示属性(Visible = false);
当点击按钮时切换页面,改变显示属性;
如下代码所示
当前有四个容器
group_voltage、group_soc、group_soh、group_fujia
private void Btn_Volatage_Click(object sender, EventArgs e) {//电压显示 State_Show = 0; group_voltage.Visible = true; group_soc.Visible = false; group_soh.Visible = false; group_fujia.Visible = false; } private void Btn_SOC_Click(object sender, EventArgs e) {//SOC显示 State_Show = 1; group_voltage.Visible = false; group_soc.Visible = true; group_soh.Visible = false; group_fujia.Visible = false;
//this.group_soc.BringToFront(); } private void Btn_SOH_Click(object sender, EventArgs e) { State_Show = 2; group_voltage.Visible = false; group_soc.Visible = false; group_soh.Visible = true; group_fujia.Visible = false;
} private void Btn_ADD_Click(object sender, EventArgs e) { State_Show = 3; group_voltage.Visible = false; group_soc.Visible = false; group_soh.Visible = false ; group_fujia.Visible = true; } |
2、动态生成文本框数组
利用一个循环,不断声明,在每个循环中,首先先声明一个控件类,然后修改她的名字(也就是ID),再者修改它的TEXT,长度,宽度。
然后最后有一句将标签或者文本框装入容器
group_voltage.Controls.Add(Label_Voltage);//将字符添加到容器group_voltage中
[小提示] Control是什莫? Control是控件类;容器类控件有此属性,因为他的内部可以添加控件。 |
此处有个问题,就是容器如果拖拉到重合的话,会发生一个问题,容器1可能被拉入容器2,就是容器被放入容器。我们需要的是这几个容器是独立的。
那么需要怎末解决呢?
我们一开始不要将其位置属性调好。只需要一个调好即可,其他的打乱。
如下图所示:
图中四个方框就是四个容器,然后我们在代码初始化中对其进行操作。
也就是每各容器需要设置宽度
//设置宽度
this.group_voltage.Width = 552;
this.group_voltage.Height = 363;
然后其他容器还需要多设定一个,让容器的Location和容器1相等。
group_soc.Location = group_voltage.Location;
下方示例代码,有文本框以及标签的声明。
对于标签文字,我们直接循环来实现。
而对于文本框,我们需要改变文本框里面的值,所以我们采用数组。
在主程序中需要声明四个数组,全局变量。
/*声明数据数组*/
/*1电池电压数组2电池SOC数组3电池SOH数组*/
TextBox[] Voltage_Battery = new TextBox[5 * 20];
TextBox[] Soc_Battery = new TextBox[5 * 20];
TextBox[] Soh_Battery = new TextBox[5 * 20];
TextBox[] Fj_Battery = new TextBox[5 * 20];
之后对数组操作部分代码如下所示
public void PAGE_Init() { //声明暂存变量 int i=0,j=0; //1电池组电压容器创建 //添加文本框与字符 for (i = 0; i < 5;i++ ) { for (j=0;j<20;j++) { //创建标签与显示窗体 Label Label_Voltage = new Label(); //设置标签属性 Label_Voltage.Name = "Label_Volatage" + (i + j * 5 + 1).ToString(); Label_Voltage.Text = "电池" + (i + j * 5 + 1).ToString(); Label_Voltage.Width = Width_Label; Label_Voltage.Height = Height_Label; //位置确定 Label_Voltage.Location = new Point(15 + i * (Width_Label + Width_Text + 6), 15 + j * (12 + Height_Label)); group_voltage.Controls.Add(Label_Voltage);//将字符添加到容器1中 //电池组电压数组设置 Voltage_Battery[i + j * 5] = new TextBox();//注意!!!先声明对象 Voltage_Battery[i + j * 5].Name = "Voltage_Battery" + i.ToString(); Voltage_Battery[i + j * 5 ].Text = (i + j * 5 + 1).ToString(); Voltage_Battery[i + j * 5].Width = Width_Text; Voltage_Battery[i + j * 5].Height = Height_Text; Voltage_Battery[i + j * 5 ].Location = new Point(67 + i * (Width_Label + Width_Text + 6), 11 + j * (4 + Height_Text)); group_voltage.Controls.Add(Voltage_Battery[i + j * 5]);//将电压组添加到容器1中 } } //设置宽度 this.group_voltage.Width = 552; this.group_voltage.Height = 363;
//SOC容器搭建 //添加文本框与字符 for (i = 0; i < 5; i++) { for (j = 0; j < 20; j++) { //创建标签 Label Label_Soc = new Label(); //设置标签属性 Label_Soc.Name = "Label_SOC" + (i + j * 5 + 1).ToString(); Label_Soc.Text = "SOC" + (i + j * 5 + 1).ToString(); Label_Soc.Width = Width_Label; Label_Soc.Height = Height_Label; //设置文本框数组属性 Soc_Battery[i + j * 5] = new TextBox();//注意!!!先声明对象 Soc_Battery[i + j * 5].Name = "SOC_Battery" + (i + j * 5 + 1).ToString(); Soc_Battery[i + j * 5].Text = (i + j * 5 + 1).ToString(); Soc_Battery[i + j * 5].Width = Width_Text; Soc_Battery[i + j * 5].Height = Height_Text; //位置确定 Label_Soc.Location = new Point(15 + i * (Width_Label + Width_Text + 6), 15 + j * (12 + Height_Label)); group_soc.Controls.Add(Label_Soc);//将字符添加到容器2中 Soc_Battery[i + j * 5].Location = new Point(67 + i * (Width_Label + Width_Text + 6), 11 + j * (4 + Height_Text)); group_soc.Controls.Add(Soc_Battery[i + j * 5]);//将SOC添加到容器2中 } } //设置宽度位置 this.group_soc.Width = 552; this.group_soc.Height = 363; group_soc.Location = group_voltage.Location; } |
3、文本框内容改变
当文本框内容需要改变时,我们直接修改TEXT即可。
下面还有一个遍历控件的函数可以检测控件中符合要求的。(做保留学习用)
如下代码如下所示
foreach (Control C in group_voltage.Controls)//遍历容器中每个控件 { if (C.Name == "Voltage_Battery10") {//如果此控件的名字为?则 C.Text = temp1.ToString(); temp1++; }
} /**/ |
【功能目标】
1、外部插件使用学习
2、对数据进行EXCEL保存
【效果图】
效果图如下所示:
【代码讲解】
1、添加引用
首先在资源管理器中添加引用,如下图所示。右击添加引用
再到扩展里面寻找需要用到的插件。
譬如我们使用EXCEL插件
如下图所示(EXCEL插件)
此时你就可以再程序中调用EXCEL了。
2、创建新建文件窗口
此处需要用到一个类SaveFileDialog
相关介绍参考官方文件
https://msdn.microsoft.com/zh-cn/library/system.windows.forms.savefiledialog.aspx
我们需要掌握的总结如下
//可能要获取的路径名 string localFilePath = "", fileNameExt= "", newFileName= "", FilePath = ""; SaveFileDialog saveFileDialog = new SaveFileDialog(); //设置文件类型 //书写规则例如:txt files(*.txt)|*.txt saveFileDialog.Filter = "txt files(*.txt)|*.txt|xls files(*.xls)|*.xls|All files(*.*)|*.*"; //设置默认文件名(可以不设置) saveFileDialog.FileName = "siling-Data"; //主设置默认文件extension(可以不设置) saveFileDialog.DefaultExt = "xml"; //获取或设置一个值,该值指示如果用户省略扩展名,文件对话框是否自动在文件名中添加扩展名。(可以不设置) saveFileDialog.AddExtension = true; //设置默认文件类型显示顺序(可以不设置) saveFileDialog.FilterIndex = 2; //保存对话框是否记忆上次打开的目录 saveFileDialog.RestoreDirectory = true; // Show save file dialog box DialogResult result = saveFileDialog.ShowDialog(); //点了保存按钮进入 if (result == DialogResult.OK) { //获得文件路径 localFilePath = saveFileDialog.FileName.ToString(); //获取文件名,不带路径 //fileNameExt = localFilePath.Substring(localFilePath.LastIndexOf("\\") + 1); //获取文件路径,不带文件名 //FilePath = localFilePath.Substring(0, localFilePath.LastIndexOf("\\")); //给文件名前加上时间 //newFileName = DateTime.Now.ToString("yyyyMMdd") + fileNameExt; //在文件名里加字符 //saveFileDialog.FileName.Insert(1,"dameng"); //为用户使用 SaveFileDialog 选定的文件名创建读/写文件流。 //System.IO.FileStream fs = (System.IO.FileStream)saveFileDialog.OpenFile();//输出文件 //fs可以用于其他要写入的操作 } |
设计代码如下
private string ShowSaveFileDialog() { string localFilePath = "";// fileNameExt, newFileName, FilePath; SaveFileDialog sfd = new SaveFileDialog();//保存文件窗口 //设置文件类型 sfd.Filter = "Excel文件(*.xlsx)|*.xlsx";//保存类型为EXCEL //保存对话框是否记忆上次打开的目录 sfd.RestoreDirectory = true; //点了保存按钮进入 if (sfd.ShowDialog() == DialogResult.OK) { localFilePath = sfd.FileName.ToString(); //获得文件路径 //string fileNameExt = localFilePath.Substring(localFilePath.LastIndexOf("\\") + 1); //获取文件名,不带路径 //获取文件路径,不带文件名 //FilePath = localFilePath.Substring(0, localFilePath.LastIndexOf("\\")); } return localFilePath;//返回值为地址 } |
3、文件写入
介绍一个Application类
Microsoft.Office.Interop.Excel.Application - 就是我们的excel应用程序类。
Workbook - 就是我们平常见的一个个excel文件,经常是使用Workbooks类对其进行操作。
Worksheet - 就是excel文件中的一个个sheet页。
Worksheet.Cells[row, column] - 就是某行某列的单元格,注意这里的下标row和column都是从1开始的,跟我平常用的数组或集合的下标有所不同。
首先创建一个EXCEL文档,调用上面我们做得那个方法。
然后新建一个EXCEL类,然后操作如下程序所示
private void Btn_DataSave_Click(object sender, EventArgs e) {//数据存储 /*******************数据导入Excel**********************/ string fileName = ShowSaveFileDialog(); //文件的保存路径和文件名 try { // 创建Excel文档类 Microsoft.Office.Interop.Excel.Application ExcelApp = new Microsoft.Office.Interop.Excel.Application(); //创建EXCEL文档 Microsoft.Office.Interop.Excel.Workbook ExcelDoc = ExcelApp.Workbooks.Add(Type.Missing); // 创建一个EXCEL页 Microsoft.Office.Interop.Excel.Worksheet xlSheet = ExcelDoc.Worksheets.Add(Type.Missing, Type.Missing, Type.Missing, Type.Missing); ExcelApp.DisplayAlerts = false; // 单元格下标是从[1,1]开始的 xlSheet.Cells[1, 1] = "序号"; xlSheet.Cells[1, 2] = "电压"; xlSheet.Cells[1, 3] = "SOC"; xlSheet.Cells[1, 4] = "SOH"; xlSheet.Cells[1, 5] = "温度"; //遍历存数据 for (int i = 0; i < 100; i++) { xlSheet.Cells[i + 2, 1] = "电池" + i.ToString(); } for (int i = 0; i < 100;i++ ) { xlSheet.Cells[i + 2, 2] = Voltage_Battery[i].Text; } for (int i = 0; i < 100; i++) { xlSheet.Cells[i + 2, 3] = Soc_Battery[i].Text; } for (int i = 0; i < 100; i++) { xlSheet.Cells[i + 2, 4] = Soh_Battery[i].Text; } // 文件保存完毕输出信息 //将此页保存到我们新建的文档中 xlSheet.SaveAs(fileName); //释放EXCEL资源 ExcelDoc.Close(Type.Missing, fileName, Type.Missing); ExcelApp.Quit(); MessageBox.Show("数据保存成功!"); } catch { MessageBox.Show("数据保存失败!"); } } |
更多介绍参考
https://wenku.baidu.com/view/a753ecc4b4daa58da1114a5e.html
详细代码请到GitHub上获取
https://github.com/Harryjun/BMS