zoukankan      html  css  js  c++  java
  • C# DataGridView自动保存列的宽度和位置

       WinForm程序中表单的自动保存列的宽度和位置,是一种常见的功能,对于用户体验来说是非常好的。现记录一下实现过程:

        1、新建一个类,命为为:DataGridViewColumnStyle。

        这个类实现的功能:当DataGridView的列宽或列的位置发生改变时,系统将自动记录DataGridView的设置。当用户下次打开此窗体的时候,表单的样式是他上次设置的模样。代码如下:

    复制代码
        class DataGridViewColumnStyle
        {
            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("Width");           //列宽度
                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)
                    {
                        if (dgvTarget.Columns.Contains(row["Name"].ToString().Trim()) && dgvTarget.Columns[row["Name"].ToString().Trim()].Visible == true)
                        {
                            dgvTarget.Columns[row["Name"].ToString().Trim()].Width = int.Parse(row["Width"].ToString().Trim());
                            dgvTarget.Columns[row["Name"].ToString().Trim()].DisplayIndex = int.Parse(row["DisplayIndex"].ToString().Trim());
                        }
                    }
                }
                catch (Exception ex)
                {
                    DeleteColumnStyle();
                    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.Width + '|' + col.DisplayIndex;
                        }
                    }
                    int colsCount = columnStyle.Length;
                    //保存列样式
                    dtColumnStyle.Rows.Clear();
                    for (int i = 0; i < colsCount; i++)
                    {
                        string[] str = new string[3];
                        try
                        {
                            DataRow newRow = dtColumnStyle.NewRow();
                            str = columnStyle.GetValue(i).ToString().Split('|');
                            newRow["Name"] = str[0];
                            newRow["Width"] = str[1];
                            newRow["DisplayIndex"] = str[2];
                            dtColumnStyle.Rows.Add(newRow);
                        }
                        catch
                        {
                            continue;
                        }
                    }
                    dtColumnStyle.WriteXml(path);
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.Message, "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
                }
            }
    
            /// <summary>
            /// 删除列样式
            /// </summary>
            private void DeleteColumnStyle()
            {
                try
                {
                    if (File.Exists(path))
                    {
                        File.Delete(path);
                    }
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.Message, "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
                }
            }
        }
    复制代码

        2、以上这些,已经实现了全部的功能。下面开始建一个WinForm程序来测试结果,为方便测试将DataGridView的数据源由xml文件读取。

              从SQL Server数据库随便找张数据表生成XML,文件保存为Test.xml。(请将Test.xml文件拷贝到Debug文件夹下面)

    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')

        3、新建一个WinForm程序,命名为Main,并拖入一个DataGridView控件,请保留【启用列重新排序】的勾选。

        Main_Load方法如下:

    复制代码
            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);
                }
            }
    复制代码

        4、执行程序,随意拖动或拉宽DataGridView列,然后重新进一次程序即可看到效果:

     

         好了,分享就到此结束了,希望对有此需要的人有一些帮助。

  • 相关阅读:
    day38 20-Spring与Junit整合
    day38 19-Spring整合web开发
    day38 18-Spring的XML和注解的结合使用
    day38 17-Spring的Bean的属性注入:注解方式
    day38 16-Spring的Bean的装配:注解的方式
    day38 15-Spring的配置文件引入的问题
    day38 14-Spring的Bean的属性的注入:集合属性的注入
    day38 13-Spring的Bean的属性的注入:SpEL注入
    day38 12-Spring的Bean的属性的注入:名称空间p
    SqlServer与.NET的数据类型映射关系图
  • 原文地址:https://www.cnblogs.com/roak/p/14173350.html
Copyright © 2011-2022 走看看