您好,登錄后才能下訂單哦!
前言
這周跟C#打了一周的交道(本周是學校安排的實驗周,然后用到了C#實現想要的程序和功能)
一共七個實驗,選擇三個,我就選擇我進步最大的一個來分析一下吧。
效果
先來看一下效果吧
從txt文本中讀取數據后展示出來
點擊目標后選中,然后點擊“修改”,彈出修改界面,然后進行編輯即可
點擊“統計”按鈕,彈出窗口顯示各分數段的信息
點擊“查詢”后,彈出界面,輸入后,點擊“確定”即可顯示信息
實現
一、準備工作
在寫方法之前,首先就是先把界面規劃好,就是通過添加按鈕和輸入框或顯示框組成一個符合要求的窗口或多個窗口
在這個程序中我們用到的主要是這幾個組件
對文件進行操作要進行引用的聲明,即“using”
我們添加的是這兩行
然后我們還要寫一些代碼來實現其他功能
public Form1() { InitializeComponent(); this.listView1.Columns.Add("學號", 100, HorizontalAlignment.Center); this.listView1.Columns.Add("姓名", 100, HorizontalAlignment.Center); this.listView1.Columns.Add("數學", 100, HorizontalAlignment.Center); this.listView1.Columns.Add("英語", 100, HorizontalAlignment.Center); this.listView1.Columns.Add("政治", 100, HorizontalAlignment.Center); this.listView1.Columns.Add("總分", 100, HorizontalAlignment.Center); this.listView1.Columns.Add("平均分", 100, HorizontalAlignment.Center); this.listView1.Columns.Add("名次", 100, HorizontalAlignment.Center); this.listView1.View = System.Windows.Forms.View.Details; this.listView1.FullRowSelect = true;//是否可以選擇行 }
“listview1”就是按鈕上方實現顯示的控件,“this”指的就是Form1這個窗口,“Columns”指的是“欄”,也就是上方的內容,“add”指的是把后面的內容作為“Columns”的內容,后面的“100”等都是“Columns”的屬性,可以通過修改它的屬性來修改它的大小和位置,還有一種生成“Column”的方法是通過屬性欄來添加。
點擊listview一次選中它,然后右鍵單擊一次,點擊屬性,會發現有“Column”這個屬性,點進去后就可以進行編輯和修改了。
不得不說確實挺方便的,不過實驗報告手冊中給了部分必須的源碼,再加上自己第一次接觸C#,所以就沒使用后面的方法,不過在后面的操作中使用了一下,確實挺爽。
二、讀取操作
這里的“讀取”按鈕讀取的是統計之后的內容,并非成績等信息,雙擊“讀取”按鈕后即可進行編輯(在按鈕的屬性中我修改了name屬性為load,所以此處的方法名為“load_Click”)
private void load_Click(object sender, EventArgs e) { this.load_data(); }
此處調用了“load_data()”這個方法
public void load_data() { string file = File.ReadAllText("Score.txt", UTF8Encoding.Default); //把txt文件中按行存儲的信息利用regex.Split按行存入string數組中 string[] records = Regex.Split(file, "\r\n"); //開始更新視圖 this.listView1.BeginUpdate(); //清空原有視圖 this.listView1.Items.Clear(); // records.Length為數組的元素個數 for (int index = 0; index < records.Length; index++) { //分割每行記錄的各個字段 string[] components = Regex.Split(records[index], " "); //生成listview的一行 ListViewItem lvi = new ListViewItem(components); //添加背景色 lvi.SubItems[0].BackColor = Color.Red; //把新生成的行加入到listview中 this.listView1.Items.Add(lvi); } //視圖更新結束 this.listView1.EndUpdate(); }
這個方法就是以“/r/n”為分界線定義一個數組1,然后再以空格為分界線定義一個數組2,同時生成一個 ListViewItem 來顯示數組2,然后再設置一下背景色,此處設置的為紅色
//生成listview的一行 ListViewItem lvi = new ListViewItem(components); //添加背景色 lvi.SubItems[0].BackColor = Color.Red;
lvi是新生成的listview的命名
三、查詢操作
private void Search_Click(object sender, EventArgs e) { Form3 f3 = new Form3(); f3.Show(); }
在查詢的方法中我們調用了一個窗口Form3,同Form1一樣,先規劃好窗口的格局,然后再寫方法
private void go_Click(object sender, EventArgs e) { string file = File.ReadAllText("Score.txt", UTF8Encoding.Default); //把txt文件中按行存儲的信息利用regex.Split按行存入string數組中 string[] records = Regex.Split(file, "\r\n"); //開始更新視圖 this.listView1.BeginUpdate(); //清空原有視圖 this.listView1.Items.Clear(); // records.Length為數組的元素個數 for (int index = 0; index < records.Length; index++) { //分割每行記錄的各個字段 string[] components = Regex.Split(records[index], " "); Regex r = new Regex(this.textBox1.Text); // 定義一個Regex對象實例 Match m = r.Match(components[0]); // 在字符串中匹配 if (m.Success) { //生成listview的一行 ListViewItem lvi = new ListViewItem(components); //添加背景色 lvi.SubItems[0].BackColor = Color.White; //把新生成的行加入到listview中 this.listView1.Items.Add(lvi); } else if (components.Length > 1) { Match n = r.Match(components[1]); if (n.Success) { //生成listview的一行 ListViewItem lvi = new ListViewItem(components); //添加背景色 lvi.SubItems[0].BackColor = Color.White; //把新生成的行加入到listview中 this.listView1.Items.Add(lvi); } } } //視圖更新結束 this.listView1.EndUpdate(); }
主要的方法,甚至是唯一的方法,就是上方的“go_Click()”方法,“Score.txt”是存放成績等信息的,在姓名和學號之中匹配,匹配到了就新建一個listview的item展示信息
這里的查詢用到了匹配的函數Match() ,在此給出官方的鏈接
Match()
四、刪除
刪除的思想就是選中要刪除的那一行,之后從文件讀取所有內容,新建string數組存放每一行,一行一行的遍歷,直到遇見選中的那一行,從數組中移除,然后把剩余的數組元素寫入文本中,WriteAllLines()方法定義中調用了replace()方法,因此省去了我們刪除文件原有內容的操作
private void Delate_Click(object sender, EventArgs e)//刪除 { foreach (ListViewItem lvi in listView1.SelectedItems) { //把txt文件內容讀入到file中,然后對string對象file進行相關處理 string file = File.ReadAllText("Score.txt", UTF8Encoding.Default); List<string> lines = new List<string>(Regex.Split(file, "\r\n")); lines.RemoveAt(lvi.Index); File.WriteAllLines("Score.txt", lines.ToArray(), UTF8Encoding.Default); } this.load_data(); }
五、錄入
private void Input_Click(object sender, EventArgs e)//錄入 { Form2 f = new Form2(this); f.Show(); }
這里的錄入方法調用了一個新的窗口Form2,與之前不同的是,這里給Form2傳了一個參數“this”,即Form1這個窗口,因為之后我們要在Form2的方法中調用Form1的方法。
再來看一下Form2的界面和方法
1、接收參數
private Form1 form; public Form2() { InitializeComponent(); } public Form2(Form1 form){ this.form = form; InitializeComponent(); }
首先進行定義,然后進行賦值,這樣的話在之后就可以用定義時使用的名稱進行Form1的方法的調用了。
2、保存信息
在點擊“保存”按鈕后,我們要實現文本的寫入以及界面的更新,文本的寫入我們要寫新的方法,界面的更新我們可以調用Form1的方法。
if (this.textBox1.Text != string.Empty && this.textBox2.Text != string.Empty && this.textBox3.Text != string.Empty && this.textBox4.Text != string.Empty && this.textBox5.Text != string.Empty) { //利用string的加法操作構造新紀錄,作為一行,寫入txt文件中 string newrecord = this.textBox1.Text + " " + this.textBox2.Text + " " + this.textBox3.Text + " " + this.textBox4.Text + " " + this.textBox5.Text + "\r\n" ; File.AppendAllText("Score.txt", newrecord, UTF8Encoding.Default); //結束form2的調用 this.Dispose(false); //調用Form1加載界面的方法 this.form.load_data(); } else { Form5 f5 = new Form5(); f5.Show(); }
首先判空,如果都不為空,定義新的字符串,賦值,寫入文本,為了保證程序的嚴謹性,加一個Form5窗口進行錯誤的提示
(由于時間的限制,這里也不算很完善,有能力的可以考慮進行各個條件的判斷,例如“學號”為空,則彈出的窗口顯示“學號不能為空”)
值得注意的是,這里調用的Form1中的方法必須是公有的,即“public”。
六、運算
private void operate_Click(object sender, EventArgs e) { //把txt文件內容讀入到file中,然后對string對象file進行相關處理 string file = File.ReadAllText("Score.txt", UTF8Encoding.Default); //把txt文件中按行存儲的信息利用regex.Split按行存入string數組中 string[] records = Regex.Split(file, "\r\n"); //開始更新視圖 this.listView1.BeginUpdate(); //清空原有視圖 this.listView1.Items.Clear(); System.IO.File.WriteAllText("Score.txt", string.Empty); double[] score1 = new double[records.Length]; double[] score2 = new double[records.Length]; int num = 0; // records.Length為數組的元素個數 for (int index = 0; index < records.Length; index++) { if (records[index].Length != 0) { //分割每行記錄的各個字段 string[] components = Regex.Split(records[index], " "); score1[index] = Convert.ToDouble(components[2]) + Convert.ToDouble(components[3]) + Convert.ToDouble(components[4]); score2[index] = (Convert.ToDouble(components[2]) + Convert.ToDouble(components[3]) + Convert.ToDouble(components[4])) / 3.0; num++; } else break; } //冒泡法排序 int temp; for (int i = 0; i < num; i++) { temp = i; for (int j = i + 1; j < num; j++) { if (score1[j] > score1[temp]) temp = j; } double t = score1[temp]; score1[temp] = score1[i]; score1[i] = t; } for (int index = 0; index < records.Length; index++) { if (records[index].Length != 0) { //分割每行記錄的各個字段 string[] components = Regex.Split(records[index], " "); for (int i = 1; i <= num; i++) { if (score1[i - 1] == Convert.ToDouble(components[2]) + Convert.ToDouble(components[3]) + Convert.ToDouble(components[4])) { //利用string的加法操作構造新紀錄,作為一行,寫入txt文件中 string newrecord = components[0] + " " + components[1] + " " + components[2] + " " + components[3] + " " + components[4] + " " + score1[i - 1] + " " + score2[index] + " " + i + "\r\n"; File.AppendAllText("Score.txt", newrecord, UTF8Encoding.Default); } } } else break; } //視圖更新結束 this.listView1.EndUpdate(); //刷新界面 this.load_data(); }
題目的要求是計算各學生總分、平均分以及排名,思想就是,先讀取文件,存儲數據,清空文件,定義總成績和平均成績兩個數組,分別計算每個人的總成績與平均成績,然后用冒泡法對總成績進行排序,得到排名,然后構造新數組拼接這些內容,再把數組寫入文本,更新視圖即可。
七、修改
修改的思想很簡單,雖說實現了想要的功能,但是也有缺陷,也沒想到特別好的解決辦法,先來說一下思路吧,首先選中,然后點擊“修改”,彈窗,在這里尤其注意得是,彈窗里對應位置要顯示選中的內容
在這個圖中,我選中的是第二行,那么我就要把它對應的數據顯示上去,在實驗過程中很多人所謂的修改就是輸入新的數據,里面所有的內容都得再寫一遍,這樣的系統,自己用著指定難受。
(說到這我想插上一件事,吐槽一下最近使用的二課系統吧,是一個微信小程序,這是學校某個團隊開發的,總體上還是可以的,最大的不足就是每次打開都得登錄,也就是說每次使用都得重新輸入賬號和密碼,用戶的體驗真的挺差的,但是也不能因為它有不足就否認它,總體上也算挺方便的,值得去學習)
因為以前參與過項目的開發,而且項目的受眾就是我們自己,也知道什么樣的效果更能使用戶滿意,所以對修改這個功能也算是有所了解,在實驗中,絕大多數人的“修改”功能都沒能達到滿意的效果,所以說經驗積累絕對不是毫無用處的。
繼續回到我們的功能實現中來,點擊“確定”后,寫入文本,那么我們肯定要把之前的數據刪掉,在傳參后立即刪除數據,當然這也就產生了瑕疵,用戶不修改數據,那怎么辦,先來看代碼吧,看完就知道了。
private void modify_Click(object sender, EventArgs e)//修改 { if (listView1.SelectedItems.Count != 0 ) { ListViewItem all = this.listView1.SelectedItems[0]; Form6 f6 = new Form6(all,this); f6.Show(); //把數據傳輸過去之后立即刪除數據 foreach (ListViewItem lvi in listView1.SelectedItems) { //把txt文件內容讀入到file中,然后對string對象file進行相關處理 string file = File.ReadAllText("Score.txt", UTF8Encoding.Default); List<string> lines = new List<string>(Regex.Split(file, "\r\n")); lines.RemoveAt(lvi.Index); File.WriteAllLines("Score.txt", lines.ToArray(), UTF8Encoding.Default); } } else { Form4 f4 = new Form4(); f4.Show(); } }
如果選中的內容不為空,那就把它的數據存到ListViewItem類型的數組中,然后傳給Form6(修改數據窗口的類),同時再把Form1這個類傳過去,以便調用它的方法,然后使用一個刪除方法,如果內容為空,彈出Form4,提示錯誤。
同樣的,在Form6這邊先定義,然后接收參數,賦值
private void Form6_Load(object sender, EventArgs e) { this.textBox1.Text = this.content.SubItems[0].Text; this.textBox2.Text = this.content.SubItems[1].Text; this.textBox3.Text = this.content.SubItems[2].Text; this.textBox4.Text = this.content.SubItems[3].Text; this.textBox5.Text = this.content.SubItems[4].Text; }
在加載方法中為textBox賦值,以此來顯示數據,修改后點擊“確定”,確定的方法和“錄入”功能的“確定”的方法相同,說白了就是寫入,如果“取消”怎么辦,數據已經刪除了,既然textBox里本來就有數據,那么就把那些數據再寫入文本,這樣雖然實現了我的功能,但是有瑕疵,就是無論修改數據與否,重新加載后數據都會顯示在最后一行。
“確定”方法
private void Determine_Click(object sender, EventArgs e) { if (this.textBox1.Text != string.Empty && this.textBox2.Text != string.Empty && this.textBox3.Text != string.Empty && this.textBox4.Text != string.Empty && this.textBox5.Text != string.Empty) { //利用string的加法操作構造新紀錄,作為一行,寫入txt文件中 string newrecord = this.textBox1.Text + " " + this.textBox2.Text + " " + this.textBox3.Text + " " + this.textBox4.Text + " " + this.textBox5.Text + "\r\n"; File.AppendAllText("Score.txt", newrecord, UTF8Encoding.Default); var lines = File.ReadAllLines("Score.txt").Where(arg => !string.IsNullOrWhiteSpace(arg)); File.WriteAllLines("Score.txt", lines); //結束form6的調用 this.Dispose(false); } this.form.load_data(); }
八、統計
所謂的統計就是計算各科各分數段人數以及各科平均分
private void Sta_Click(object sender, EventArgs e)//統計 { this.Output(); Form7 f7 = new Form7(); f7.Show(); }
調用一個output()方法,用Form7顯示數據
public string Output()//寫入數據 { string add = string.Empty; add += "統計情況:" + "\r\n" + "分數段" + "," + "數學" + "," + "英語" + "," + "政治" + "\r\n"; add += "<60" + "," + GetGradeSection(1, 0, 59).ToString() + "," + GetGradeSection(2, 0, 59).ToString() + "," + GetGradeSection(3, 0, 59).ToString() + "\r\n"; add += "60~69" + "," + GetGradeSection(1, 60, 69).ToString() + "," + GetGradeSection(2, 60, 69).ToString() + "," + GetGradeSection(3, 60, 69).ToString() + "\r\n"; add += "70~79" + "," + GetGradeSection(1, 70, 79).ToString() + "," + GetGradeSection(2, 70, 79).ToString() + "," + GetGradeSection(3, 70, 79).ToString() + "\r\n"; add += "80~89" + "," + GetGradeSection(1, 80, 89).ToString() + "," + GetGradeSection(2, 80, 89).ToString() + "," + GetGradeSection(3, 80, 89).ToString() + "\r\n"; add += "90~100" + "," + GetGradeSection(1, 90, 100).ToString() + "," + GetGradeSection(2, 90, 100).ToString() + "," + GetGradeSection(3, 90, 100).ToString() + "\r\n"; add += "平均分" + "," + GetAve(1).ToString() + "," + GetAve(2).ToString() + "," + GetAve(3).ToString() + "\r\n"; System.IO.File.WriteAllText("List.txt", string.Empty); File.AppendAllText("List.txt", add, UTF8Encoding.Default); return add; }
Output方法調用了GetGradeSection()和 GetAve() 兩個方法,先生成并定義字符串數組,然后把兩個方法返回的數據與原有的信息拼接到數組中,再寫入即可。
public double GetGradeSection(int m ,int low, int high)//分數段 { int count = 0; string file = File.ReadAllText("Score.txt", UTF8Encoding.Default); //把txt文件中按行存儲的信息利用regex.Split按行存入string數組中 string[] records = Regex.Split(file, "\r\n"); //開始更新視圖 this.listView1.BeginUpdate(); //清空原有視圖 this.listView1.Items.Clear(); // records.Length為數組的元素個數 for (int index = 0; index < records.Length; index++) { //分割每行記錄的各個字段 if (records[index].Length != 0) { string[] components = Regex.Split(records[index], " "); if (m == 1)//數學 { if (Convert.ToDouble(components[2]) >= low && Convert.ToDouble(components[2]) <= high) { count++; } } if (m == 2)//英語 { if (Convert.ToDouble(components[3]) >= low && Convert.ToDouble(components[3]) <= high) { count++; } } if (m == 3)//政治 { if (Convert.ToDouble(components[4]) >= low && Convert.ToDouble(components[4]) <= high) { count++; } } } else break; } return count; }
先循環,然后進行判斷,如果在分數段內就把count值加一,最后返回到Output()方法中
public double GetAve(int m)//平均分 { double ave = 0; string file = File.ReadAllText("Score.txt", UTF8Encoding.Default); //把txt文件中按行存儲的信息利用regex.Split按行存入string數組中 string[] records = Regex.Split(file, "\r\n"); int length = records.Length; //開始更新視圖 this.listView1.BeginUpdate(); //清空原有視圖 this.listView1.Items.Clear(); // records.Length為數組的元素個數 for (int index = 0; index < records.Length; index++) { if (records[index].Length != 0) { //分割每行記錄的各個字段 string[] components = Regex.Split(records[index], " "); if (m == 1) { ave += double.Parse(components[2]); } if (m == 2) { ave += double.Parse(components[3]); } if (m == 3) { ave += double.Parse(components[4]); } } else break; } return ave/length; }
把各科對應的所有的分數加在一起,然后除以總人數,即為平均分,返回到Output()方法中
拼接好的字符串數組寫入List.txt文本中,在Form7中讀取,在Listview中顯示即可
九、清除
清除就是清空所有的文本數據,然后就把空字符寫入覆蓋即可
private void ClearAll_Click(object sender, EventArgs e) { System.IO.File.WriteAllText("Score.txt", string.Empty); System.IO.File.WriteAllText("List.txt", string.Empty); this.load_data(); }
總結
由于之前沒接觸過C#,所以也不知道怎么搞,總結下來就是這一周的收獲并不是很大,畢竟整天忙得不可開交,吃飯、睡覺、敲代碼,最后一總結發現并沒有學到什么真切的知識,畢竟一點都沒學,上來就用,這種方式真的難以理解,在此我想說的是,只要敢鉆研,肯鉆研,再難的問題也有解決的辦法,最后補充一句,忙點真的挺好的,每天都很充實,加油,奮斗在路
好了,以上就是這篇文章的全部內容了,希望本文的內容對大家的學習或者工作具有一定的參考學習價值,謝謝大家對億速云的支持。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。