图片插入功能,这个是Excel插件的一大刚需,但目前在VBA接口里开发,如果用S方法插入的图片,没法对其添加事件,且图片插入后需等比例调整纵横比例特别麻烦,特别是对于插入的多个图片非统一的纵横尺寸比时。

例如一个很经典的需求是将插入的缩略图放大操作,没法点击、双击之类的事件响应对应的放大操作。

在VBA的方法中,还有一个方式,用窗体控件Image,可以实现图片插入后有事件关联。



窗体控件Image方法插入

但很遗憾的是,这个方法中插入的图片,当没有点选图片时,图片会有些模糊的情况。具体可对比下图左右部分。这个模糊的问题,还是老大难,难于达到完美。如果换成是VSTO的宿主项PictureBox,就完美解决了。



两种不同窗体控件方式插入图片

例如下图中的,用鼠标右键事件,调出上下文菜单。和Excel催化剂中的双击图片进行图片下载本地并调用Windows图片查看器实现图片的放大功能。



可以关联事件的插入图片方法


双击图片事件


保留有正确的原始图片纵横比例

笔者觉得这是个接近完美的解决方案(用窗体控件的方式插入图片,用户不能直接选择图片、移动图片,会有种奇怪的感觉)。

具体实现

使用VSTO的PictureBox容器,将其图片属性设置成对应的图片对象即可,此处传入的图片对象是Image对象,不必像VBA方法里的只能传入文件全路径,可以方便某些数据库等方式存储二进制图片格式时,直接调用。

public static string AddPictureBoxToVstoWorkShee dstRange, Image img, string fileExt, bool hasBordersMargin, bool isLookupFromRangValue, int OffsetRow, int offsetCol) { string picName = Guid.NewGuid().ToString(); Excel.Worksheet actSht = d; Worksheet vstoActSht = Globals.Fac(actSht); PictureBox pictureBox = new PictureBox(); = img; = Pic; += PictureBox_MouseDoubleClick; AddContextMenutopictureBox(pictureBox); = picName; ControlSite controlSite; if (hasBordersMargin) { controlSite = v( control: pictureBox, top: d + 2, left: d + 2, height: d - 4, width: d - 4, name: picName); } else { controlSite = v( control: pictureBox, range: dstRange, name: picName); } string srcFileName = ; Excel.Range srcFileNameRange = null; if (isLookupFromRangValue) { //取回图片文件名的单元格,可拿到文件名,我初始的单元格地址,为后面有可能插入过行、列来重新定位。 srcFileNameRange = d[-offsetRow, -offsetCol]; srcFileName = srcFileNameRange == null ? "" : (); } Common.v( new En() { PicName = picName, IsLookupFromRangValue = isLookupFromRangValue, PicOleName = con, PicSht = actSht, SrcFileNameRange = srcFileNameRange, DstRange = dstRange, SrcFileName = srcFileName, ImageExt = fileExt, PictureBoxImage = img }); return picName; }

其中核心代码有:

得到一个VSTO的WorkSheet对象和新建一个PictureBox对象。

Excel.Worksheet actSht = d; Worksheet vstoActSht = Globals.Fac(actSht); PictureBox pictureBox = new PictureBox(); = img; = Pic;

通过方法v进行创建一个Picturebox到工作表中。具体各参数的意义和VBA的AddPicture方法类似,可自行查阅文档。

controlSite = v( control: pictureBox, top: d + 2, left: d + 2, height: d - 4, width: d - 4, name: picName);

通过以上的方法,即可创建了一个PictureBox对象容器,并且图片是我们传入的图片。这当中可以绑定一些PictureBox事件和上下文菜单等,如:

+= PictureBox_MouseDoubleClick; private static void AddContextMenuToPictureBox(PictureBox pictureBox) { ContextMenuStrip contextMenuStrip = new ContextMenuStrip(); string[] btnsText = { "复制另存为", "移动至其他区域", "删除图片" }; foreach (var btnText in btnsText) { ToolStripButton toolStripButton = new ToolStripButton(btnText); = pictureBox; += PictureBoxToolStripButton_Click; con(toolStripButton); } = contextMenuStrip; }

通过此方法插入的PictureBox,保存关闭后,Excel文件因无法在关闭状态下存储PictureBox对象,将会将其转换为OLE对象存储,设置过的事件将失效,Excel催化剂用了复杂的手段来恢复它,下篇其他技术时再进行介绍

结语

图片插入这样一个刚需功能,在Excel催化剂上已经将其做到极致化的体验,也是有别于传统方式所实现的,在用户体验上,相信有对比后,也会喜欢上Excel催化剂这样的突破性的方式。

此篇已经对核心的技术及代码完成开源公开化,有兴趣的朋友们,可以一试。

1.《如何在vs窗体中用图片》援引自互联网,旨在传递更多网络信息知识,仅代表作者本人观点,与本网站无关,侵删请联系页脚下方联系方式。

2.《如何在vs窗体中用图片》仅供读者参考,本网站未对该内容进行证实,对其原创性、真实性、完整性、及时性不作任何保证。

3.文章转载时请保留本站内容来源地址,https://www.lu-xu.com/keji/3268229.html