Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/262.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# PowerPoint互操作:按主控文件中定义的名称获取占位符_C#_Powerpoint_Office Interop_Powerpoint Automation - Fatal编程技术网

C# PowerPoint互操作:按主控文件中定义的名称获取占位符

C# PowerPoint互操作:按主控文件中定义的名称获取占位符,c#,powerpoint,office-interop,powerpoint-automation,C#,Powerpoint,Office Interop,Powerpoint Automation,在我的PowerPoint加载项中,我希望访问幻灯片上的形状。这些形状是在slidemaster的自定义布局中定义的占位符 当我根据自定义布局添加幻灯片时,形状只会被命名为“占位符1”、“占位符2” 有没有办法通过主控中给定的名称获取占位符 目前我正在使用以下代码搜索形状: public static Shape GetShape(string stringToSearch, Shapes shapes) { foreach (Shape shape in shapes) {

在我的PowerPoint加载项中,我希望访问幻灯片上的形状。这些形状是在slidemaster的自定义布局中定义的占位符

当我根据自定义布局添加幻灯片时,形状只会被命名为“占位符1”、“占位符2”

有没有办法通过主控中给定的名称获取占位符

目前我正在使用以下代码搜索形状:

public static Shape GetShape(string stringToSearch, Shapes shapes) {

        foreach (Shape shape in shapes) {

            if (shape.Name == stringToSearch) {
                return shape;
            }

            // Search Groups
            if (shape.Type == MsoShapeType.msoGroup) {
                foreach (Shape childshape in shape.GroupItems) {
                    if (childshape.Name == stringToSearch) {
                        return childshape;
                    }
                }
            }
        }

        throw new KeyNotFoundException("No Shape found");
}

更新: 也许更清楚地说,这是PowerPoint演示文稿的结构

为占位符定义名称的主控形状:

母版中定义的名称丢失的演示文稿:

问题:如何通过主控中定义的名称获取演示文稿中的元素?

嗯。。这是史蒂夫的“丑陋”解决方案

对于我的项目,我既没有也不想控制形状的创建,所以我不能“标记”它们。这就是为什么我有一个自定义的占位符名称来标识它们,所以形状的名称实际上是[placeholder Type]##

步骤如下:

  • 存储所有形状的位置
  • 重置幻灯片布局
  • 匹配幻灯片形状和主幻灯片形状
  • 恢复所有形状的位置
注意:我不使用形状组。如果你这样做了,这个技巧会变得复杂得多,你需要检查组内的情况

这是执行此操作并返回mastershapename-shapename映射的函数

专用词典GetShapeMasters(Powerpoint.s)
{
Dictionary shapeMasters=新字典();
列表形状位置=新列表();
//门店位置
foreach(s.Shapes中的Powerpoint.Shape sh)
{
添加(新的ShapeLocation()
{
Name=sh.Name,
位置=新系统。图纸。矩形F(左侧、顶部、宽度、高度)
});
}
//让powerpoint重新设置幻灯片
//问题:这会更改没有内容的占位符的名称。
s、 CustomLayout=s.CustomLayout;
//比较幻灯片和母版
foreach(s.Shapes中的Powerpoint.Shape sh)
{
foreach(s.CustomLayout.Shapes中的Powerpoint.Shape msh)
{
if(IsShapeMaster(上海、msh))
{
shapeMasters[msh.Name]=sh.Name;
}
}
}
//还原位置
//TODO:可能被“撤消”替换
foreach(形状位置中的var shm)
{
Powerpoint.Shape sh=null;
尝试
{
sh=s.Shapes[shm.Name];
}
抓住
{
//重命名占位符形状失败。
//还没有找到一种合适的方法来检查形状名称是否存在。
}
//占位符无论如何都不需要还原。
如果(sh!=null)
{
sh.Left=shm.Location.Left;
sh.Top=shm.Location.Top;
sh.宽度=shm.Location.Width;
sh.高度=shm.位置.高度;
}
}
返回成型器;
}
有了这个你可以做到

Dictionary shapeMasters=GetShapeMasters(幻灯片);
if(shapeMasters.ContainsKey(stringToSearch))
Powerpoint.Shape KnownShape=theSlide[shapeMasters[stringToSearch];
这是一个比较函数,它采用两种形状并检查它们是否“相等”。可以扩展以使其更精确

private bool-IsShapeMaster(Powerpoint.Shape-sh、Powerpoint.Shape-msh)
{
返回
sh.Left==msh.Left
&&sh.Top==msh.Top
&&sh.宽度==msh.宽度
&&sh.高度==msh.高度
&&sh.Type==msh.Type
&&sh.PlaceholderFormat.Type==msh.PlaceholderFormat.Type;
}
存储原始形状位置的小类

类形状定位
{
公共字符串名称;
公共系统。图纸。矩形位置;
}

我愿意接受建议,因为我也不喜欢这样。只是似乎没有其他方法将形状和占位符链接在一起。确实没有一些
形状。MasterShape
我们缺少了,是吗?

自定义布局上有什么类型的占位符,它们是如何添加/命名的?在我看来,幻灯片上的形状似乎与自定义布局上的形状名称匹配,除非您重命名自定义布局上的形状;然后幻灯片上匹配的形状会得到一个类似于[Placeholder Type]###的名称(该数字似乎与主控/布局上形状的名称没有关系)。在这种情况下,您可能需要在幻灯片和布局上迭代shapes集合以查找匹配的占位符类型。然后,如果给定占位符类型中有多个占位符类型,则可能需要临时复制幻灯片并重新应用布局(以便幻灯片上的形状恢复其原始位置)然后通过比较大小/位置找到正确的主控形状/布局形状。丑!一个是图像占位符,另一个是文本占位符。占位符被命名为picImage和txtName。这意味着有人在创建占位符时将其从指定为默认名称的PPT中重命名,因此您必须加倍努力才能将其排序。很抱歉如果“某人”的意思是PowerPoint,那么你是对的。没有人重新命名某个东西。PowerPoint的默认行为是将占位符命名为“占位符1”、“占位符2”。。。