【C#】Winform开发笔记(持续更新)
随便写写,主要是记录。
ListView使用方法
最近在做即时通讯,有一个需求是要显示好友列表
以前在安卓里可以有个适配器来写样式,C#貌似很麻烦,索性写简单点。
private void initListView() { ColumnHeader cJC = new ColumnHeader();//创建一个列 cJC.Text = "好友编号";//列名 cJC.Width = 100; ColumnHeader cKC = new ColumnHeader(); cKC.Text = "好友昵称"; cKC.Width = 200; lv_main.Columns.AddRange(new ColumnHeader[] { cJC, cKC }); lv_main.View = View.Details;//列的显示模式 for (int i = 0; i < 10; i++) { String[] words = { "10"+(i+1), "好友"+(i+1) }; lv_main.Items.Add(new ListViewItem(words)); } }
监听事件
private void lv_main_SelectedIndexChanged(object sender, EventArgs e) { try { ListView.SelectedIndexCollection indexes = this.lv_main.SelectedIndices; if (indexes.Count > 0) { int index = indexes[0]; string sPartNo = this.lv_main.Items[index].SubItems[0].Text;//获取第一列的值 string sPartName = this.lv_main.Items[index].SubItems[1].Text;//获取第二列的值 MessageBox.Show(sPartNo + "|" + sPartName, "SUCCESS"); } } catch (Exception ex) { MessageBox.Show("操作失败!\n" + ex.Message, "提示", MessageBoxButtons.OK, MessageBoxIcon.Exclamation, MessageBoxDefaultButton.Button1); } }
另外,如果需要设置列表一行选中,去属性窗口把FullRowSelect设置为true即可。
设置窗口居中
目前控件不能根据窗口大小来动态调整,索性就直接禁用最大最小、居中显示即可。
MaximizeBox 是否可以最大化 MinimizeBox 是否可以最小化 this.StartPosition = FormStartPosition.CenterScreen;//居中显示
Post/Get封装
注意你的.Net版本,4.0以上才可以设置Tls12协议。
System.Net.ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
public class HttpUitls { public static string Get(string Url) { System.Net.ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12; HttpWebRequest request = (HttpWebRequest)WebRequest.Create(Url); request.Proxy = null; request.KeepAlive = false; request.Method = "GET"; request.ContentType = "application/json; charset=UTF-8"; request.AutomaticDecompression = DecompressionMethods.GZip; HttpWebResponse response = (HttpWebResponse)request.GetResponse(); Stream myResponseStream = response.GetResponseStream(); StreamReader myStreamReader = new StreamReader(myResponseStream, Encoding.UTF8); string retString = myStreamReader.ReadToEnd(); myStreamReader.Close(); myResponseStream.Close(); if (response != null) { response.Close(); } if (request != null) { request.Abort(); } return retString; } public static string Post(string Url, string Data, string Referer) { System.Net.ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12; HttpWebRequest request = (HttpWebRequest)WebRequest.Create(Url); request.Method = "POST"; request.Referer = Referer; byte[] bytes = Encoding.UTF8.GetBytes(Data); request.ContentType = "application/x-www-form-urlencoded"; request.ContentLength = bytes.Length; Stream myResponseStream = request.GetRequestStream(); myResponseStream.Write(bytes, 0, bytes.Length); HttpWebResponse response = (HttpWebResponse)request.GetResponse(); StreamReader myStreamReader = new StreamReader(response.GetResponseStream(), Encoding.UTF8); string retString = myStreamReader.ReadToEnd(); myStreamReader.Close(); myResponseStream.Close(); if (response != null) { response.Close(); } if (request != null) { request.Abort(); } return retString; } }
另外补充一个带参数的Post方法
public static string Post(string url, Dictionary<string, string> dic) { string result = ""; HttpWebRequest req = (HttpWebRequest)WebRequest.Create(url); req.Method = "POST"; req.ContentType = "application/x-www-form-urlencoded"; #region 添加Post 参数 StringBuilder builder = new StringBuilder(); int i = 0; foreach (var item in dic) { if (i > 0) builder.Append("&"); builder.AppendFormat("{0}={1}", item.Key, item.Value); i++; } byte[] data = Encoding.UTF8.GetBytes(builder.ToString()); req.ContentLength = data.Length; using (Stream reqStream = req.GetRequestStream()) { reqStream.Write(data, 0, data.Length); reqStream.Close(); } #endregion HttpWebResponse resp = (HttpWebResponse)req.GetResponse(); Stream stream = resp.GetResponseStream(); //获取响应内容 using (StreamReader reader = new StreamReader(stream, Encoding.UTF8)) { result = reader.ReadToEnd(); } return result; }
文件输入输出
文件写入
String txtpath = System.AppDomain.CurrentDomain.BaseDirectory.ToString() + "dataBase\\lessons.txt"; String subpath = System.AppDomain.CurrentDomain.BaseDirectory.ToString() + "dataBase"; if (File.Exists(txtpath)) { FileStream stream2 = File.Open(txtpath, FileMode.OpenOrCreate, FileAccess.Write); stream2.Seek(0, SeekOrigin.Begin); stream2.SetLength(0); //清空txt文件 StreamWriter sw = new StreamWriter(stream2); sw.Write(str); sw.Flush(); sw.Close(); stream2.Close(); } else { if (false == System.IO.Directory.Exists(subpath)) { //创建pic文件夹 System.IO.Directory.CreateDirectory(subpath); } FileStream fs = new FileStream(txtpath, FileMode.CreateNew); StreamWriter sw = new StreamWriter(fs); sw.Write(str); sw.Flush(); sw.Close(); fs.Close(); }
文件读取
if (File.Exists(txtpath)) { StreamReader sr = new StreamReader(txtpath, Encoding.UTF8); String line; String input_str = ""; while ((line = sr.ReadLine()) != null) { input_str = input_str + line; } sr.Close(); //TODO } else { //不存在 }
两个form传数据
需求:主窗口A,点击一个按钮弹出B窗口采集信息后传输给A
思路:创建一个监听回调,参数传递。
在B中写一个接口(以登录为例)
public interface IOnLogin { void Login(String username, String pass, String term); }
这里就写你需要实现的逻辑,函数中的参数为想传递的,如本例中使用B采集username,pass,term并传递给A来处理。
在B中设置一个全局的接口变量,如
private IOnLogin loginlistener;
并设置一个public的方法来设置该接口
public void setIOnLogin(IOnLogin listener) { loginlistener = listener; }
然后就可以在要实现的地方去调用了,如在点击按钮时:
private void btn_login_Click(object sender, EventArgs e) { loginlistener.Login(tb_account.Text,tb_pass.Text,cb_term.Text); this.Close(); }
紧接着我们在A中来实现这个接口
这里要吐槽一下C#不能写匿名接口类???写习惯了Android这种太难受了。
private class MyLoginListener : UserAccountInputForm.IOnLogin { private Form1 form; public MyLoginListener(Form1 form) { this.form = form;//这里加一个form是方便调用静态成员变量 } public void Login(string username, string pass, string term) { //业务逻辑 } }
然后在启动B的时候设置监听:
UserAccountInputForm userAccountInputForm = new UserAccountInputForm(); userAccountInputForm.setIOnLogin(new MyLoginListener(this)); userAccountInputForm.Show();
OK。
像在Android写那种多个Frame的时候也是一样的原理,如果要传递数据就让MainFrameActivity作为中间传递者即可。
解析JSON
Json多香啊,可以一键转成实体。。。
准备一个json字符串,然后使用工具 JSON转C#实体类 转换一下就可以得到映射实体类。
我准备的是自己的课表:
[{"id":0,"name":"人工智能1","time":"","room":"21107","teacher":"林民安副教授","weekList":[1,2,3,4,5,6,7,8,9,10,11,12],"start":1,"step":2,"day":1,"term":"2019-2020-2","colorRandom":0},{"id":0,"name":"Linux操作系统(双语)","time":"","room":"12305","teacher":"外教3Amir其他","weekList":[1,3,4,6,7,8,10,11,12,14,15,16],"start":1,"step":2,"day":2,"term":"2019-2020-2","colorRandom":0},{"id":0,"name":"人工智能1","time":"","room":"12301","teacher":"林民安副教授","weekList":[1,3,5,7,9,11],"start":1,"step":2,"day":3,"term":"2019-2020-2","colorRandom":0},{"id":0,"name":"工程经济学","time":"","room":"12307","teacher":"林宪鸿副教授","weekList":[1,2,3,4,5,6,7,8,9,10,11],"start":1,"step":2,"day":4,"term":"2019-2020-2","colorRandom":0},{"id":0,"name":"工程经济学","time":"","room":"12306","teacher":"林宪鸿副教授","weekList":[1,2,3,4,5,6,7,8,9,10,11],"start":1,"step":2,"day":5,"term":"2019-2020-2","colorRandom":0},{"id":0,"name":"软件工程3","time":"","room":"21206","teacher":"王坤德副教授","weekList":[1,2,3,4,5,6,7,8,9,10,11],"start":3,"step":2,"day":2,"term":"2019-2020-2","colorRandom":0},{"id":0,"name":"Linux操作系统(双语)","time":"","room":"11111","teacher":"未知老师","weekList":[1,2,5,9,13],"start":3,"step":2,"day":3,"term":"2019-2020-2","colorRandom":0},{"id":0,"name":"文献检索1","time":"","room":"22202","teacher":"干林馆员","weekList":[1,2,3,4,5],"start":3,"step":2,"day":4,"term":"2019-2020-2","colorRandom":0},{"id":0,"name":"软件工程3","time":"","room":"12507","teacher":"王坤德副教授","weekList":[1,2,3,4,5,6,7,8,9,10,11],"start":3,"step":2,"day":5,"term":"2019-2020-2","colorRandom":0},{"id":0,"name":"JavaEE应用程序开发","time":"","room":"22308","teacher":"陈剑洪副教授","weekList":[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17],"start":5,"step":2,"day":4,"term":"2019-2020-2","colorRandom":0},{"id":0,"name":"网络编程技术4","time":"","room":"12301","teacher":"于坤副教授,付磊其他","weekList":[1,2,3,4,5,6,7,8,9,10,11,12,13],"start":7,"step":2,"day":1,"term":"2019-2020-2","colorRandom":0},{"id":0,"name":"信息隐藏技术","time":"","room":"21206","teacher":"陈剑洪副教授","weekList":[1,2,3,4,5,6,7,8,9,10,11,12,13],"start":7,"step":2,"day":4,"term":"2019-2020-2","colorRandom":0}]
吐槽一下,像这种Json数组他就不认了吗???生成class0---classn可太秀了
不用管它,只需要根对象即可,即:
public class JsonLessons { /// <summary> /// /// </summary> public int id { get; set; } /// <summary> /// 人工智能1 /// </summary> public string name { get; set; } /// <summary> /// /// </summary> public string time { get; set; } /// <summary> /// /// </summary> public string room { get; set; } /// <summary> /// 林民安副教授 /// </summary> public string teacher { get; set; } /// <summary> /// /// </summary> public List<int> weekList { get; set; } /// <summary> /// /// </summary> public int start { get; set; } /// <summary> /// /// </summary> public int step { get; set; } /// <summary> /// /// </summary> public int day { get; set; } /// <summary> /// /// </summary> public string term { get; set; } /// <summary> /// /// </summary> public int colorRandom { get; set; } }
然后我们需要一个强大的解析工具(正则?别吧,太烦了,有轮子不用?)Json.Net
官网可能比较慢,这里提供一个下载地址:https://dl.pconline.com.cn/download/2427479.html
把里面的dll文件拿出来,然后使用资源管理器引用导入就好了~
using Newtonsoft.Json;
如何使用呢?
很简单,就一句话:
List<JsonLessons> results = JsonConvert.DeserializeObject<List<JsonLessons>>(jsonstr);
因为我们知道是Json数组,所以直接设置为List<>即可。
打包安装
好了,软件写好了怎么用呢?我们使用了扩展库,还想设置图标,要能做成安装程序的形式多好···
VS2019中已经把这个功能砍掉了···所以我们需要单独的去下载这个扩展包
Microsoft Visual Studio Installer Projects
去扩展里下载一下就好,如果下载速度慢的话可以直接到官网使用迅雷下载。安装即可。
过程很简单这里就不再赘述了,虽然是英文的但基本都能看懂。
美化
天哪,都2020年了C#做出来的界面怎么还这么丑!
不慌,直接上扩展库:CSkin
用过有点非主流????emmm凑合着用吧,反正桌面软件讲究实用嘛(强行解释)