VSTO Word 和 Visual basic:Shape.Left 属性 不接受赋值

VSTO Word & Visual basic: Shape.Left property does not take on assigned value

我想在文档每一页的右上角放置一个徽标。此功能已存在于由我们管理的 Word 加载项中。但是,此功能无法正常工作。加载项将图像转换为形状,然后将此图像放置在距文档左角固定距离处。这适用于 A4 格式的文档,但只要文档的方向或大小发生变化,徽标位置就会关闭。

我尝试了很多策略来解决这个问题,但还没有找到令人满意的方法。我目前的策略是动态确定左侧页面和徽标之间的距离,然后通过调用 .RelativeHorizo​​ntalPosition 属性 并将其链接到右边距区域,使该位置相对于页面右侧。

不幸的是,与 Shape 对象的 .Left 属性 交互很麻烦。 .Left 属性 不采用我分配的值,而是采用负值。我已经多次检查了我分配给它的参数。谁知道为什么会这样以及如何解决?

示例代码

Private Sub AddLogos(section As Section, header As HeaderFooter)
    Dim wordApp As Word.Application = Globals.ThisAddIn.Application
    Dim pageWidth As Single = section.PageSetup.PageWidth
    Dim imgFilePath As String = "filepath"
    Dim leftDistanceA4 As Single = 11
    Dim logo As Word.Shape

    Try
        If wordApp.ActiveDocument.SaveFormat >= 12 Then
            logo = header.Range.InlineShapes.AddPicture(m_sImageLogo, False, True).ConvertToShape()
        Else 'Word 97-2003 Support
            logo = header.Shapes.AddPicture(imgFilePath, False, True)
        End If
    Catch ex As Exception
        Throw New Exception("Error message.")
    End Try

    Dim distanceFromRightPageEdge = wordApp.CentimetersToPoints(21 - leftDistanceA4)
    Dim distanceFromLeftPageEdge = pageWidth - distanceFromRightPageEdge

    With logo
      .RelativeVerticalPosition = WdRelativeVerticalPosition.wdRelativeVerticalPositionPage
      .Left = distanceFromLeftPageEdge
      .RelativeHorizontalPosition = WdRelativeHorizontalPosition.wdRelativeHorizontalPositionRightMarginArea
    End With

与其将左侧位置设置为绝对值,不如将其设置为相对值,本质上是 "right-align" 形状。如果您如下所示设置 RelativeHorizo​​ntalPosition 和 Left 属性,图像将放置在 top-right 角,并且即使文档的格式或大小发生变化,图像也将保持与该角的相对位置。

    Const imgpath As String = "[your path]"

    Dim app As New Microsoft.Office.Interop.Word.Application
    Dim doc As Microsoft.Office.Interop.Word.Document = app.Documents.Add()
    Dim head As Microsoft.Office.Interop.Word.HeaderFooter = doc.Sections(1).Headers(1)
    Dim img As Microsoft.Office.Interop.Word.Shape = head.Shapes.AddPicture(imgpath, False, True)
    With img
        .RelativeHorizontalPosition = Microsoft.Office.Interop.Word.WdRelativeHorizontalPosition.wdRelativeHorizontalPositionMargin
        .Left = Microsoft.Office.Interop.Word.WdShapePosition.wdShapeRight
    End With
    app.Visible = True

    'dispose references

Edit: If you need more control over positioning than simply anchoring the image to the top-right corner of the page, inline shapes do not inherently possess that. Instead, consider using a borderless table in the header to provide more control over its contents. Once the image is a child of the table, you have access to all the table formatting controls to use on your image:

    Const imgpath As String = "[your path]"
    Const imgMarginCM As Integer = 2

    Dim app As New Microsoft.Office.Interop.Word.Application
    Dim doc As Microsoft.Office.Interop.Word.Document = app.Documents.Add()
    Dim head As Microsoft.Office.Interop.Word.HeaderFooter = doc.Sections(1).Headers(1)
    Dim tbl As Microsoft.Office.Interop.Word.Table = doc.Tables.Add(head.Range, 1, 1)
    With tbl
        .Borders.Enable = False
        .AutoFitBehavior(Microsoft.Office.Interop.Word.WdAutoFitBehavior.wdAutoFitWindow)
        .Cell(1, 1).Range.ParagraphFormat.Alignment = WdParagraphAlignment.wdAlignParagraphRight
        .Cell(1, 1).TopPadding = app.CentimetersToPoints(imgMarginCM)
        .Cell(1, 1).RightPadding = app.CentimetersToPoints(imgMarginCM)
        .Cell(1, 1).Range.InlineShapes.AddPicture(imgpath, False, True)
    End With
    app.Visible = True

    'dispose references

当然,如果您在 header 中还有其他项目,那么您将创建一个包含多个单元格的 table 并适当调整间距,但对于这个示例,我只是放置一个无边框的single-cell table 在 header 中并将其自动调整行为设置为 fitwindow 以便 table 将填充页面的宽度,即使页边距或格式已更改。然后我只用图像设置单元格的顶部和右侧填充,您正在寻找的行为就实现了。