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(, 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 = ; i < colsCount; i++)
{
string[] str = new string[];
try
{
DataRow newRow = dtColumnStyle.NewRow();
str = columnStyle.GetValue(i).ToString().Split('|');
newRow["Name"] = str[];
newRow["Width"] = str[];
newRow["DisplayIndex"] = str[];
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 > ? ds.Tables[] : null;
//加工dataGridView1
#region 加列标题测试
dataGridView1.Columns[].HeaderText = "制令单号";
dataGridView1.Columns[].HeaderText = "成品编号";
dataGridView1.Columns[].HeaderText = "生产数量";
dataGridView1.Columns[].HeaderText = "来源单号";
#endregion
DataGridViewColumnStyle style = new DataGridViewColumnStyle(dataGridView1);
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
}

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

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

DataGridView自动保存列的宽度和位置的更多相关文章

  1. 如何不让DataGridView自动生成列

    如果不想让DataGridView自动生成与数据源对应的列, 只需要把属性AutoGenerateColumns设为false即可. 需要注意: 在界面设计的属性窗口中是看不到AutoGenerate ...

  2. datagridview自动填充列头

    //填充datagridview dgv.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.Fill;

  3. C# 禁止datagridview 自动产生列

    dataGridView1.AutoGenerateColumns = false;

  4. 【转】如何不让DataGridView自动生成列

    源地址:https://www.cnblogs.com/hailexuexi/p/3983856.html

  5. DatagridView自动充满屏幕,并能指定某列宽度

    1.要使datagridview正好充满屏幕,设置其AutoSizeColumnsMode属性为fill 2. 同时,我们想要某列宽点,某列窄点,在AutoSizeColumnsMode属性为fill ...

  6. [Winform]DataGridView列自适应宽度

    引言 在做winform项目中,数据控件DataGridView的使用多多少少是会用到的,如果不设置它的属性,默认情况下是不会自适应宽度的,你想查看某项的数据,就不得不将标题栏拖来拖去,挺烦的. 方法 ...

  7. ## GridView 布局:item设置的高度和宽度不起作用、自动适配列数、添加Header和Footer ##

    一.item设置的高度和宽度不起作用 转自:http://www.cnblogs.com/0616--ataozhijia/p/6031875.html [Android Pro] listView和 ...

  8. DataGridView列自适应宽度

    来源:http://www.cnblogs.com/wolf-sun/p/3480104.html 在做winform项目中,数据控件DataGridView的使用多多少少是会用到的,如果不设置它的属 ...

  9. DataGridView列的宽度、行的高度自动调整

    注意:DataGridView控件是从.NET Framework 2.0版本开始追加的. 介绍一下DataGridView列的宽度和行的高度,根据单元格或Header的内容(一般是内容全部被表示)自 ...

随机推荐

  1. C# 中的委托和事件(一)

    引言 委 托 和 事件在 .Net Framework中的应用非常广泛,然而,较好地理解委托和事件对很多接触C#时间不长的人来说并不容易.它们就像是一道槛儿,过了这个槛的人,觉得真 是太容易了,而没有 ...

  2. 了解 MongoDB 看这一篇就够了【华为云技术分享】

    版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明. 本文链接:https://blog.csdn.net/devcloud/article/detai ...

  3. 0-N-0计数的优化写法

    采用取余%的写法: int i = 0; while( 1 ) { printf( "%d\n", i ); i = ( i + 1 ) % ( N + 1 );}

  4. mq解决分布式事物问题

    今天只看看原理,下一节看项目怎么集成mq进行解决分布式事物. 1.什么情况下会使用到分布式事物? 举例说明:现有一个支付系统,因为项目使用的是微服务框架,有订单模块和支付模块两个模块.生产者进行订单的 ...

  5. 论文阅读 | Sentence-BERT: Sentence Embeddings using Siamese BERT-Networks

    简述 在文本语义相似度等句子对的回归任务上,BERT , RoBERTa 拿到sota. 但是,它要求两个句子都被输入到网络中,从而导致巨大开销:从10000个句子集合中找到最相似的sentence- ...

  6. redis位图巧用,节约内存

    最近要做一个圣诞抽奖活动,需要记录每天用户签到的记录,以前一般都是用普通的字符串数据类型,每个用户的签到用一个 key // 用户10在活动第一天的签到key为record:1:10 $key = & ...

  7. HDU1944 S-NIM(多个NIM博弈)

    Arthur and his sister Caroll have been playing a game called Nim for some time now. Nim is played as ...

  8. Selenium之编辑框操作

    编辑框操作: 网页上随处可见的编辑框,有时候编辑框里有默认的提示文字或者当我们需要输入第二次测试数据时,须先用clear()方法清除该元素里的字符串,再输入文本: 那么如何获取输入框已经输入的文本内容 ...

  9. 【Vuejs】301- Vue 3.0前的 TypeScript 最佳入门实践

    前言 我个人对更严格类型限制没有积极的看法,毕竟各类转类型的骚写法写习惯了. 然鹅最近的一个项目中,是 TypeScript+ Vue,毛计喇,学之...-真香! 1. 使用官方脚手架构建 npm i ...

  10. Spring与Shiro整合 加载权限表达式

    Spring与Shiro整合 加载权限表达式 作者 : Stanley 罗昊 [转载请注明出处和署名,谢谢!] 如何加载权限表达式  我们在上章内容中画了一张图,里面有三个分项,用户 角色 权限: 那 ...