首先,尝试使用, .Item 不 .ItemU ,这两个是不同的功能。默认值(您在VBA中隐式使用的那个)是 Item 。您可能实际上在c#中处理不同的形状
.Item
.ItemU
Item
第二, .Text 应该以大写字母T开头,小t的代码不应该编译。确保这一点 .text 小写不是从某处导入的扩展方法,(与Visio无关)
.Text
.text
第三个警告 - 为了确保在UI中看到形状的文本,最好使用 shape.Characters.Text ,因为如果形状包含字段, shape.Text 将为那些字段文本应该去的地方返回占位符('obj')。但这适用于VBA和C#
shape.Characters.Text
shape.Text
第四.. groupShape 在VBA中似乎是变量名称,而不是形状名称。从代码中不清楚该组形状的名称是什么。你如何在VBA中获得那个?可能值得一试。
groupShape
和往常一样,我来找出.Text返回“Obj”的原因是形状中没有任何文字。如果有文本,它将返回它。我太过追赶了回归,“Obj”。我想知道为什么它不返回空文本或null如果形状中没有文本。无论如何,这个问题的所有其他答案都非常有用,它们引导我找到问题所在。
我对Visio类型库不是很熟悉,但是这个:
groupShape.shapes.item("rectangle")
回来了 Shape 宾语。抓住该对象引用而不是用另一个点丢弃它。 VBA在这里是“有用的”,并且很高兴让你编写只能在运行时解决的后期绑定调用--C#只会是那个允许的 dynamic 关键字,您通常不希望编码 dynamic - 你想使用强类型:
Shape
dynamic
Dim rectangle As Shape Set rectangle = groupShape.shapes.item("rectangle") Dim rectangleText As String rectangleText = rectangle.Text
C#/ interop代码需要做同样的事情:
var groupShape = (Shape)Doc.Shapes.ItemU("groupShape"); var rectangle = (Shape)groupShape.Shapes.ItemU("rectangle"); var rectangleText = rectangle.Text // assuming Text is defined on the Shape interface
换句话说,始终要知道您正在使用的类型;如果一个成员返回一个 object 并且您需要它是一个更具体的类型,您需要在成员调用的编译时验证之前进行适当的转换,或者转换为 dynamic 如果您不关心编译时验证并将它们推迟到运行时:
object
var text = (string)((dynamic)groupShape.Shapes.ItemU("rectangle")).Text
注意演员表 string ; text 将是一个 string 。忘记演员表,你的代码必须处理 dynamic 像癌症一样遍布执行路径并破坏你的类型安全 - 而你却不希望这样。
string
text