WinForm程序中表單的自動保存列的寬度和位置,是一種常見的功能,對於用戶體驗來講是很是好的。現記錄一下實現過程:數據庫
一、新建一個類,命爲爲:DataGridViewColumnStyle。函數
這個類實現的功能:當DataGridView的列寬或列的位置發生改變時,系統將自動記錄DataGridView的設置。當用戶下次打開此窗體的時候,表單的樣式是他上次設置的模樣。代碼以下:測試
private DataGridView dgvTarget = null; //待處理的DataGridView對象 private string path; //文件路徑 private DataTable dtColumnStyle = null; //列樣式數據表 private bool isBindColumnStyle = false; //是否綁定列樣式否 //DataGridView屬性 public DataGridView DataGridView { get { return dgvTarget; } set { //去除事件 if (dgvTarget != null) { dgvTarget.ColumnWidthChanged += new DataGridViewColumnEventHandler(DataGridView_ColumnWidthChanged); dgvTarget.ColumnDisplayIndexChanged += new DataGridViewColumnEventHandler(DataGridView_ColumnDisplayIndexChanged); } dgvTarget = value; //註冊事件 if (dgvTarget != null) { dgvTarget.ColumnWidthChanged += new DataGridViewColumnEventHandler(DataGridView_ColumnWidthChanged); dgvTarget.ColumnDisplayIndexChanged += new DataGridViewColumnEventHandler(DataGridView_ColumnDisplayIndexChanged); } } } //無參構造函數 public DataGridViewColumnStyle() { } //有參構造函數 public DataGridViewColumnStyle(DataGridView dataGridView) : this() { DataGridView = dataGridView; //文件名 string formName = dgvTarget.FindForm().Name; string userId = "Test"; path = Application.StartupPath + @"\Accounts\" + userId + "\\" + formName + "_" + dgvTarget.Name + ".xml"; //列樣式數據表 dtColumnStyle = new DataTable(); dtColumnStyle.TableName = dgvTarget.Name; //表名 dtColumnStyle.Columns.Add("Name"); //列名 dtColumnStyle.Columns.Add("HeaderText"); //列標題 dtColumnStyle.Columns.Add("Width"); //列寬度 dtColumnStyle.Columns.Add("Visible"); //是否顯示 dtColumnStyle.Columns.Add("DisplayIndex"); //顯示順序 //綁定列樣式 BindColumnStyle(); } /// <summary> /// 綁定列樣式 /// </summary> private void BindColumnStyle() { try { //賦初始值 isBindColumnStyle = true; //若是不存在則保存列樣式 if (!File.Exists(path)) { SaveColumnStyle(); } //加載列樣式 dtColumnStyle.ReadXml(path); foreach (DataRow row in dtColumnStyle.Rows) { dgvTarget.Columns[row["Name"].ToString().Trim()].HeaderText = row["HeaderText"].ToString().Trim(); dgvTarget.Columns[row["Name"].ToString().Trim()].Width = int.Parse(row["Width"].ToString().Trim()); dgvTarget.Columns[row["Name"].ToString().Trim()].Visible = Boolean.Parse(row["Visible"].ToString().Trim()); dgvTarget.Columns[row["Name"].ToString().Trim()].DisplayIndex = int.Parse(row["DisplayIndex"].ToString().Trim()); } } catch (Exception ex) { MessageBox.Show(ex.Message, "提示", MessageBoxButtons.OK, MessageBoxIcon.Information); } finally { isBindColumnStyle = false; } } /// <summary> /// 列顯示位置改變時 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void DataGridView_ColumnDisplayIndexChanged(object sender, DataGridViewColumnEventArgs e) { if (isBindColumnStyle == false) { SaveColumnStyle(); } } /// <summary> /// 列寬度改變時 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void DataGridView_ColumnWidthChanged(object sender, DataGridViewColumnEventArgs e) { if (isBindColumnStyle == false) { SaveColumnStyle(); } } /// <summary> /// 保存列樣式 /// </summary> private void SaveColumnStyle() { try { //若是目錄不存在則建立 string dir = path.Substring(0, path.LastIndexOf('\\')); if (!Directory.Exists(dir)) { Directory.CreateDirectory(dir); } //讀取列樣式 string[] columnStyle = new string[dgvTarget.Columns.Count]; foreach (DataGridViewColumn col in dgvTarget.Columns) { if (col.Visible == true) { columnStyle[col.DisplayIndex] = col.Name + '|' + col.HeaderText + '|' + col.Width + '|' + col.Visible + '|' + col.DisplayIndex; } } int colsCount = columnStyle.Length; //保存列樣式 dtColumnStyle.Rows.Clear(); for (int i = 0; i < colsCount; i++) { string[] str = new string[5]; try { DataRow newRow = dtColumnStyle.NewRow(); str = columnStyle.GetValue(i).ToString().Split('|'); //分隔 newRow["Name"] = str[0]; newRow["HeaderText"] = str[1]; newRow["Width"] = str[2]; newRow["Visible"] = str[3]; newRow["DisplayIndex"] = str[4]; dtColumnStyle.Rows.Add(newRow); } catch { continue; } } dtColumnStyle.WriteXml(path); } catch (Exception ex) { MessageBox.Show(ex.Message, "提示", MessageBoxButtons.OK, MessageBoxIcon.Information); } } /// <summary> /// 刪除列樣式 /// </summary> private bool DeleteColumnStyle() { if (File.Exists(path)) { File.Delete(path); return true; } return false; }
二、以上這些,已經實現了所有的功能。下面開始建一個WinForm程序來測試結果,爲方便測試將DataGridView的數據源由xml文件讀取。this
從SQL Server數據庫隨便找張數據表生成XML,文件保存爲Test.xml。(請將Test.xml文件拷貝到Debug文件夾下面)spa
SELECT TOP 10 MO_NO,MRP_NO,QTY,BIL_NO FROM MF_MO WHERE MO_DD='2019-11-07' ORDER BY MO_NO FOR XML PATH ('Category'),TYPE,ROOT('DocumentElement')
三、新建一個WinForm程序,命名爲Main,並拖入一個DataGridView控件,請保留【啓用列從新排序】的勾選。code
Main_Load方法以下:orm
private void Main_Load(object sender, EventArgs e) { try { //xml文件路徑 string path = @"Test.xml"; //讀取文件 DataSet ds = new DataSet(); if (File.Exists(path)) { ds.ReadXml(path); } dataGridView1.DataSource = ds.Tables.Count > 0 ? ds.Tables[0] : null; //加工dataGridView1 #region 加列標題測試 dataGridView1.Columns[0].HeaderText = "制令單號"; dataGridView1.Columns[1].HeaderText = "成品編號"; dataGridView1.Columns[2].HeaderText = "生產數量"; dataGridView1.Columns[3].HeaderText = "來源單號"; #endregion DataGridViewColumnStyle style = new DataGridViewColumnStyle(dataGridView1); } catch (Exception ex) { MessageBox.Show(ex.Message, "提示", MessageBoxButtons.OK, MessageBoxIcon.Information); } }
四、執行程序,隨意拖動或拉寬DataGridView列,而後從新進一次程序便可看到效果:xml
好了,分享就到此結束了,但願對有此須要的人有一些幫助。對象