我想出了這個問題的解決方案似乎相當劈十歲上下,但據我所知還沒有一個更好的辦法。問題是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
接下來是使用PowerPoint Interop運行宏的C#代碼。將該文件作爲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();