Excel催化剂开源第13波-VSTO开发之DataGridView控件几个小坑

Excel催化剂内部大量使用了DataGridView,这其中有一些小坑,花了力气才解决的,在此给广大开发者作简单分享。

为何要使用DataGridView而不是其他控件如ListBox、ListView、ComboBox之类的?因为大量的数据,特别是配置信息,都是以数据库表结构的一维表存储最为合理,一般一个配置是多列内容来定义其多样的属性。

用DataGridView最有优势之处在于,可以直接让DataTable直接绑定即可,同时带有丰富的事件可与用户交互,并且保留有用户常用的排序功能,筛选功能也容易实现,用Dataview来绑定数据源即可。

使用DataGridView的一些小坑

DataGridView内复选框状态改变激活事件

在Excel催化剂的【工作表导航】功能中,有用到DataGridView存储工作表信息,需要和用户交互的是用户点击复选框,可以对工作表的显示隐藏状态进行改变。

 
image.png

若直接在Checkbox列上写CellValueChanged事件,会发现不起作用的。当然这一步也不可少。

private void dataGridView1_CellValueChanged(object sender, DataGridViewCellEventArgs e) { if (Common.ExcelApp.ActiveWorkbook.ProtectStructure == false) { if (e.RowIndex != -1 && !dataGridView1.Rows[e.RowIndex].IsNewRow) { //复选框列 if (e.ColumnIndex == 1) { string worksheetName = this.dataGridView1[0, e.RowIndex].Value.ToString(); Excel._Worksheet wht = Common.ExcelApp.ActiveWorkbook.Worksheets[worksheetName]; try { if ((bool)this.dataGridView1[e.ColumnIndex, e.RowIndex].Value == true) { wht.Visible = Excel.XlSheetVisibility.xlSheetVisible; } else { wht.Visible = Excel.XlSheetVisibility.xlSheetHidden; } } catch (Exception) { MessageBox.Show($"操作有误,错误原因为:\r\n工作薄至少需要一个工作表为可见的!"); this.dataGridView1[e.ColumnIndex, e.RowIndex].Value = true; } } } } else { MessageBox.Show("工作薄受保护状态不可操作工作表显示/隐藏操作!"); this.dataGridView1.CellValueChanged -= dataGridView1_CellValueChanged; this.dataGridView1[e.ColumnIndex, e.RowIndex].Value = true; this.dataGridView1.CellValueChanged += dataGridView1_CellValueChanged; } } 

需要加上这个事件才可生效,具体原理可自行百度

        /// <summary>
        /// 这个为了让复选框可以单击时产生变化而用的。网上抄的。
        /// </summary>
        /// <param name="sender"></param> /// <param name="e"></param> private void dataGridView1_CurrentCellDirtyStateChanged(object sender, EventArgs e) { if (dataGridView1.IsCurrentCellDirty) { dataGridView1.CommitEdit(DataGridViewDataErrorContexts.Commit); } } 
DataGridView的行手工排序问题

DataGridView原生功能没有实现通过按住某行拖动的方式实现不同行之间的排序问题。在百度上搜索了一些代码实现了此功能。

在Excel催化剂上的使用场景为,对工作表的手工排序操作。

 

 
手工排序效果

首先要打开这个AllowDrop属性

 

 
AllowDrop打开

具体代码段

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; using Excel = Microsoft.Office.Interop.Excel; namespace Excel催化剂 { public partial class formSheetSort : Form { public formSheetSort() { InitializeComponent(); this.Icon = Properties.Resources.Excel催化剂logo32; } private void formSheetSort_Load(object sender, EventArgs e) { ReloadSheetName(); } private void btnEnsureOrderSheetName_Click(object sender, EventArgs e) { try { Common.ExcelApp.ScreenUpdating = false; int shtCount = Common.ExcelApp.ActiveWorkbook.Worksheets.Count; foreach (DataGridViewRow row in this.dgv.Rows) { Excel.Worksheet sht = Common.ExcelApp.ActiveWorkbook.Worksheets[row.Cells[0].Value]; sht.Move(After: Common.ExcelApp.ActiveWorkbook.Worksheets[shtCount]); } } catch (Exception ex ) { MessageBox.Show("操作出错,出错原因为" + ex.Message); } finally { Common.ExcelApp.ScreenUpdating = true; } } private void ReloadSheetName() { foreach (Excel.Worksheet item in Common.ExcelApp.ActiveWorkbook.Worksheets) { DataGridViewRow row = new DataGridViewRow(); int sheetNameIndex = this.SheetName.Index; int rowIndex = this.dgv.Rows.Add(); this.dgv.Rows[rowIndex].Cells[sheetNameIndex].Value = item.Name; } } private int selectionIdx = 0; private void dgv_CellMouseDown(object sender, DataGridViewCellMouseEventArgs e) { if (e.RowIndex >= 0) selectionIdx = e.RowIndex; } private void dgv_CellMouseMove(object sender, DataGridViewCellMouseEventArgs e) { DataGridView dgv = sender as DataGridView; if ((e.Clicks < 2) && (e.Button == MouseButtons.Left)) { if ((e.ColumnIndex == -1) && (e.RowIndex > -1)) dgv.DoDragDrop(dgv.Rows[e.RowIndex], DragDropEffects.Move); } } private void dgv_DragDrop(object sender, DragEventArgs e) { DataGridView dgv = sender as DataGridView; int idx = GetRowFromPoint(e.X, e.Y); if (idx < 0) return; if (e.Data.GetDataPresent(typeof(DataGridViewRow))) { DataGridViewRow row = (DataGridViewRow)e.Data.GetData(typeof(DataGridViewRow)); int rowIndex = row.Index; if (idx < rowIndex) { dgv.Rows.Remove(row); selectionIdx = idx; dgv.Rows.Insert(idx, row); } else { dgv.Rows.Remove(row); selectionIdx = idx - 1; dgv.Rows.Insert(idx - 1, row); } } } private void dgv_RowsAdded(object sender, DataGridViewRowsAddedEventArgs e) { DataGridView dgv = sender as DataGridView; if (selectionIdx > -1 && dgv.Rows.Count > 0) { dgv.Rows[selectionIdx].Selected = true; dgv.CurrentCell = dgv.Rows[selectionIdx].Cells[0]; } } private void dgv_DragEnter(object sender, DragEventArgs e) { e.Effect = DragDropEffects.Move; } private int GetRowFromPoint(int x, int y) { for (int i = 0; i < this.dgv.RowCount; i++) { Rectangle rec = this.dgv.GetRowDisplayRectangle(i, false); if (this.dgv.RectangleToScreen(rec).Contains(x, y)) return i; } return -1; } } } 

结语

在.Net下写VSTO插件,没有理由再用VBA那些落后的控件,DataGridView、Ado.Net这些在.Net环境里的数据控件和数据存储技术是首选,代码书写更流畅,开发效率更高,用户体验也是超棒。

此篇给大家扫清几个小坑,让大家开发过程中,更顺畅,尽情地在业务逻辑代码上发挥,少关注底层这些莫名的坑坑洼洼。

技术交流QQ群

QQ群名:Excel催化剂开源讨论群, QQ群号:788145319

 

 
Excel催化剂开源讨论群二维码

关于Excel催化剂

Excel催化剂先是一微信公众号的名称,后来顺其名称,正式推出了Excel插件,插件将持续性地更新,更新的周期视本人的时间而定争取一周能够上线一个大功能模块。Excel催化剂插件承诺个人用户永久性免费使用!

Excel催化剂插件使用最新的布署技术,实现一次安装,日后所有更新自动更新完成,无需重复关注更新动态,手动下载安装包重新安装,只需一次安装即可随时保持最新版本!

Excel催化剂插件下载链接:https://pan.baidu.com/s/1Iz2_NZJ8v7C9eqhNjdnP3Q

 
联系作者
 
公众号

取名催化剂,因Excel本身的强大,并非所有人能够立马享受到,大部分人还是在被Excel软件所虐的阶段,就是头脑里很清晰想达到的效果,而且高手们也已经实现出来,就是自己怎么弄都弄不出来,或者更糟的是还不知道Excel能够做什么而停留在不断地重复、机械、手工地在做着数据,耗费着无数的青春年华岁月。所以催生了是否可以作为一种媒介,让广大的Excel用户们可以瞬间点燃Excel的爆点,无需苦苦地挣扎地没日没夜的技巧学习、高级复杂函数的烧脑,最终走向了从入门到放弃的道路。

最后Excel功能强大,其实还需树立一个观点,不是所有事情都要交给Excel去完成,也不是所有事情Excel都是十分胜任的,外面的世界仍然是一个广阔的世界,Excel只是其中一枚耀眼的明星,还有其他更多同样精彩强大的技术、工具等。*Excel催化剂也将借力这些其他技术,让Excel能够发挥更强大的爆发!

关于Excel催化剂作者

姓名:李伟坚,从事数据分析工作多年(BI方向),一名同样在路上的学习者。
服务过行业:零售特别是鞋服类的零售行业,电商(淘宝、天猫、京东、唯品会)

技术路线从一名普通用户,通过Excel软件的学习,从此走向数据世界,非科班IT专业人士。
历经重重难关,终于在数据的道路上达到技术平原期,学习众多的知识不再太吃力,同时也形成了自己的一套数据解决方案(数据采集、数据加工清洗、数据多维建模、数据报表展示等)。

擅长技术领域:Excel等Office家族软件、VBA&VSTO的二次开发、Sqlserver数据库技术、Sqlserver的商业智能BI技术、Powerbi技术、云服务器布署技术等等。

2018年开始职业生涯作了重大调整,从原来的正职工作,转为自由职业者,暂无固定收入,暂对前面道路不太明朗,苦重新回到正职工作,对Excel催化剂的运营和开发必定受到很大的影响(正职工作时间内不可能维护也不可能随便把工作时间内的成果公布于外,工作外的时间也十分有限,因已而立之年,家庭责任重大)。

和广大拥护者一同期盼:Excel催化剂一直能运行下去,我所惠及的群体们能够给予支持(多留言鼓励下、转发下朋友圈推荐、小额打赏下和最重点的可以和所在公司及同行推荐推荐,让我的技术可以在贵司发挥价值,实现双赢(初步设想可以数据顾问的方式或一些小型项目开发的方式合作)。

技术交流QQ群

QQ群名:Excel催化剂开源讨论群, QQ群号:788145319

 

 
Excel催化剂开源讨论群二维码

关于Excel催化剂

Excel催化剂先是一微信公众号的名称,后来顺其名称,正式推出了Excel插件,插件将持续性地更新,更新的周期视本人的时间而定争取一周能够上线一个大功能模块。Excel催化剂插件承诺个人用户永久性免费使用!

Excel催化剂插件使用最新的布署技术,实现一次安装,日后所有更新自动更新完成,无需重复关注更新动态,手动下载安装包重新安装,只需一次安装即可随时保持最新版本!

Excel催化剂插件下载链接:https://pan.baidu.com/s/1Iz2_NZJ8v7C9eqhNjdnP3Q

 
联系作者
 
公众号

取名催化剂,因Excel本身的强大,并非所有人能够立马享受到,大部分人还是在被Excel软件所虐的阶段,就是头脑里很清晰想达到的效果,而且高手们也已经实现出来,就是自己怎么弄都弄不出来,或者更糟的是还不知道Excel能够做什么而停留在不断地重复、机械、手工地在做着数据,耗费着无数的青春年华岁月。所以催生了是否可以作为一种媒介,让广大的Excel用户们可以瞬间点燃Excel的爆点,无需苦苦地挣扎地没日没夜的技巧学习、高级复杂函数的烧脑,最终走向了从入门到放弃的道路。

最后Excel功能强大,其实还需树立一个观点,不是所有事情都要交给Excel去完成,也不是所有事情Excel都是十分胜任的,外面的世界仍然是一个广阔的世界,Excel只是其中一枚耀眼的明星,还有其他更多同样精彩强大的技术、工具等。*Excel催化剂也将借力这些其他技术,让Excel能够发挥更强大的爆发!

关于Excel催化剂作者

姓名:李伟坚,从事数据分析工作多年(BI方向),一名同样在路上的学习者。
服务过行业:零售特别是鞋服类的零售行业,电商(淘宝、天猫、京东、唯品会)

技术路线从一名普通用户,通过Excel软件的学习,从此走向数据世界,非科班IT专业人士。
历经重重难关,终于在数据的道路上达到技术平原期,学习众多的知识不再太吃力,同时也形成了自己的一套数据解决方案(数据采集、数据加工清洗、数据多维建模、数据报表展示等)。

擅长技术领域:Excel等Office家族软件、VBA&VSTO的二次开发、Sqlserver数据库技术、Sqlserver的商业智能BI技术、Powerbi技术、云服务器布署技术等等。

2018年开始职业生涯作了重大调整,从原来的正职工作,转为自由职业者,暂无固定收入,暂对前面道路不太明朗,苦重新回到正职工作,对Excel催化剂的运营和开发必定受到很大的影响(正职工作时间内不可能维护也不可能随便把工作时间内的成果公布于外,工作外的时间也十分有限,因已而立之年,家庭责任重大)。

和广大拥护者一同期盼:Excel催化剂一直能运行下去,我所惠及的群体们能够给予支持(多留言鼓励下、转发下朋友圈推荐、小额打赏下和最重点的可以和所在公司及同行推荐推荐,让我的技术可以在贵司发挥价值,实现双赢(初步设想可以数据顾问的方式或一些小型项目开发的方式合作)。

转载于:https://www.cnblogs.com/ExcelCuiHuaJi/p/10579005.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
注意:本3.0版件过于老旧,该件最新版本为4.7版,您可以到http://myyouping.download.csdn.net/免费下载,也是完全免费的,没有任何功能及使用时间限制,0积分下载。我将3.0版件的下载分提为10分,是希望大家使用最新版的件。 件特色: 1、超强大的DataGridView打印功能,不光可以以多种形式(普通打印、分栏打印、跨页打印、工资条打印)打印DataGridView表格,基本上能完全按DataGridView件本身设置的格式如字体、字号、背景颜色、前景颜色、单元格对齐方式等打印出来,文字图像都可以打印,而且是完全根据表格当前的显示顺序进行打印的,如果您在使用时调整了列的顺序,刷新打印后就会按调整后的列显示顺序进行打印(这是网上很多DataGridView打印件没有实现的),基本上做到了所见即所得的打印。 2、强大的文本打印输出功能,打印文本时,如果需要,件会自动换行或换页打印输出。 3、支持同一文档多种版面格式打印(类似于Word中的节的功能):对同一份文档,不同的页面可以设置不同的格式(纸张大小、纸张方向、页边距),只需要在新增一页时在NewPage方法中指定要使用的页面格式即可,使用非常简单。 4、报表功能。本件允许将当前打印预览的内容保存为报表文件,以后使用本件重新打开该报表文件即可重现原来保存报表时的打印内容。 5、打印方案保存与读取功能。可以将当前打印参数保存为打印方案文件,或都从保存的打印方案文件中读取打印参数。 6、水印功能。根据需要,可以在页面中打印或不打印以半透明空心文字打印水印。 7、特殊文字效果功能。本版件具有打印浮雕文字、阴影文字、空心文字、块文字的功能,效果非常不错。 8、页眉页脚中既可打印文字,也可打印图像,或者即打印图像又打印输出文字。 9、图像打印输出功能。 本件包括两个打印组件:DGVprint打印组件与VB2008print打印组件。VB2008Print为通用打印件(为可视化组件),可以混合打印一个或多个DataGridView表格、DataGrid表格与文字、图片等内容;而DGVprint是以VB2008Print为基础开发的(为非可视化组件),为专用的表格打印件,可以很方便打印单个DatatGridview、DataGrid、DataTable表格的内容,并提供打印时的可视化设置界面,可设置表格打印方式(普通打印、分栏打印、跨页打印、工资条打印)、标题内容及字体、页眉页脚、选择要打印的表格列、列顺序调整及列格式设置、更改列标题名称等,使用非常方便,功能非常强大。 与本件的上一个版本2.1版相比,本版件新增功能如下: VB2008Print打印组件新增功能: 1、多种特效文字打印输出功能,能打印的特效文字有 空心文字、浮雕文字、块文字、阴影文字等。 2、水印打印功能。可以在面页中以半透明空心文字的形式打印背景水印,只需要简单设置件的WaterMarkText等几个以WaterMark开头的属性即可,程序会自动打印水印。 3、PrintDGV函数可直接使用DGVPrint组件保存的打印方案文件打印输出DataGridView表格, 4、在页眉页脚中不光可以打印文本,还可以打印图像,文本与图像可同时打印(即在图像上显示文本)。此外,页眉页脚文字可以换行打印了,页面的左边也右边距也可以打印内容了(调用相应的函数PrintLeft与PrintRight实现)。 5、改进DrawText函数输出文本的功能,现在,即便调用没有指定打印区域或打印宽度的DrawText函数输出文本,打印输出时件也会智能换行和换页(原版本是需要指定打印宽度才能自动换行换页打印的) 6、改进DrawImage与DrawCellImage输出图像功能,如果图像比较小(小于打印区域大小),可以不进行放大打印。(但如果图像大于打印区域的话,还是采用整体缩小打印,而不是区域剪裁打印)。 7、增加IsShowPrintStatusDialog属性,指示在发送到打印机打印时,是否显示一个指示正在打印的状态窗口(可以取消打印),为TRUE表示要显示,为False表示不显示。 8、改进页眉页脚事件,将原来的HeaderOut与FooterOut统一为HeaderFooterOut事件,在该事件中,您可以调用PrintFooter、PrintHeader、PrintLeft、PrintRight函数分别打印上下左右的页眉。(PrintLeft与PrintRight函数为新增加的,用于在左边与右边页边距处输出内容) DGVPrint打印组件新增功能: 1、打印方案保存与读取功能。本版件可以将您的可视化设置(包括列格式设置等)全部保存为打印方案文件(文本文件,您可以用记事本打开并修改),并有读取方案文件的功能,不再需要每次都进行打印格式设置了,一劳永逸! 2、直接调用打印方案文件打印功能。您不光可以设计DGVPrint打印组件的属性来进行打印,还可以直接调用DGVPrint组件中保存的打印方案文件,直接利用保存的方案文件的参数进行打印预览输出。 3、新增在可视化打印参数设置界面的列标题重命名功能,可能修改列标题要打印的名字。 4、水印打印功能。如果水印文本设置为空,则不打印水印。 5、导出数据成Excel功能。暂未提供该功能的函数接口,只在打印参数设置窗口中增加了一个数据导出的按钮,可以将当前要打印的DataGridView的内容导出成Excel文件。该功能以后会进一步完善。 6、在进行页眉页脚文本设置时,可以用 [页码] 代表要输出的当前页码,用 [总页数] 代表要输出总页数,件在进行输出时,会自动将其转换为对应的页码与文档总页数。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值