[英]OpenXML refresh connectors on a PowerPoint Slide automatically
我有一个简单的场景,其中我使用OpenXML SDK 2.5和c#以编程方式创建一个带有幻灯片的演示文稿。 幻灯片上有2种形状,还有一个连接这2种形状的连接器。
当我在PowerPoint中打开演示文稿时,会同时显示两个形状和连接器,但是连接器在两个形状之间的位置不正确。 当我在幻灯片上拖动一个形状时,PowerPoint立即刷新连接器并将其放置在正确的位置。
我的问题:是否可以创建一个openxml PowerPoint幻灯片,该幻灯片在打开文件时自动刷新连接器位置?
谢谢
我针对此问题想出的解决方案似乎有些破绽,但据我所知,没有更好的方法。 问题是PowerPoint内部控制了连接器的放置,并且没有公开任何刷新它们的方法。 在测试中,我惊讶地发现PowerPoint会在刷新期间根据需要动态更改连接器类型。
为了使刷新发生,我不得不在.pptm文件中编写一个VBA宏,然后从我的C#代码中调用它。 我添加了一个模块,并将函数放在那里,这样它就不会与特定的幻灯片相关联。
该代码在幻灯片上移动每种形状,以触发连接器刷新。 它也在组内寻找形状。 它正在过滤三角形和菱形形状。
我避免在代码中使用ActivePresentation,因为我想在宏运行时隐藏PowerPoint。
Public Sub FixConnectors()
Dim mySlide As Slide
Dim shps As Shapes
Dim shp As Shape
Dim subshp As Shape
Set mySlide = Application.Presentations(1).Slides(1)
Set shps = mySlide.Shapes
For Each shp In shps
If shp.AutoShapeType = msoShapeIsoscelesTriangle Or shp.AutoshapeType = msoShapeDiamond Then
shp.Left = shp.Left + 0.01 - 0.01
End If
If shp.Type = mso.Group Then
For Each subshp In shp.GroupItems
If subshp.AutoShapeType = msoShapeIsoscelesTriangle Or subshp.AutoshapeType = msoShapeDiamond Then
subshp.Left = subshp.Left + 0.01 - 0.01
End If
Next subshp
End If
Next shp
Application.Presentations(1).Save
End Sub
接下来是C#代码,以使用PowerPoint Interop运行宏。 作为Windows进程关闭并重新打开文件,垃圾回收器可以清理Interop拥有的所有句柄。 在测试中,终结器可能需要花费几秒钟来运行,因此GC调用在重新打开文件后发生,因此应用程序似乎没有挂起。
using System;
using System.Diagnostics;
using OC = Microsoft.Office.Core;
using PP = Microsoft.Office.Interop.PowerPoint;
string filePath = "C:/Temp/";
string fileName = "Template.pptm";
// Open PowerPoint in hidden mode, run the macro, and shut PowerPoint down
var pptApp = new PP.Application();
PP.Presentation presentation = pptApp.Presentations.Open(filePath + fileName, OC.MsoTriState.msoFalse, OC.MsoTriState.msoFalse, OC.MsoTriState.msoFalse);
pptApp.Run(filename + "!.FixConnectors");
presentation.Close();
presentation = null;
pptApp.Quit();
pptApp = null;
// Reopen the file through Windows
Process.Start(filePath + fileName);
// Clear all references to PowerPoint
GC.Collect();
GC.WaitForPendingFinalizers();
GC.Collect();
GC.WaitForPendingFinalizers();
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.