C# VSTO Word、PPT踩坑

参考我的VSTO之路(四):深入介绍Word开发 - Justin Zhang - 博客园 (cnblogs.com)

1、Slides (unknown member): Invalid request.  Clipboard is empty or contains data which may not be pasted here.

场景:接到一个需求,需要将一个本地PPT的所有页复制粘贴到当前PPT

使用代码

Microsoft.Office.Interop.PowerPoint.Presentation source = PPTapp.Presentations.Open(sourcePptFile, MsoTriState.msoFalse, MsoTriState.msoFalse, MsoTriState.msoFalse);
int sourceSlideRange = source.Slides.Count;

int forStart =  1 ;
int forEnd = sourceSlideRange ;
for (int i = forStart; i <= forEnd; ++i)
{
    Microsoft.Office.Interop.PowerPoint.Slide srcSlide = source.Slides[i];
    source.Slides[i].Copy();

    target.Slides.Paste(target.Slides.Count + 1);
    target.Slides[target.Slides.Count].FollowMasterBackground = MsoTriState.msoFalse;
}
View Code

但是会报错Slides (unknown member): Invalid request.  Clipboard is empty or contains data which may not be pasted here.,可能原因是是因为复制粘贴太快,剪切板异常导致的。(网上搜了很多资料,找不到具体原因)

开发中发现每次复制粘贴代码执行后界面不会立即刷新,会等待一段时间。特别是当前页面有弹窗时,复制粘贴只有当弹窗关闭后激活ppt才会生效。

因此尝试在每次复制粘贴后弹出一个弹窗,300毫秒(多次测试300比较合适,再短会有异常)后自动关闭,保证每次复制粘贴都会激活ppt窗体。

附上代码:

AtuoCloseWindow

<Window x:Class="AtuoCloseWindow"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             xmlns:local="clr-namespace:PowerPointAIAddIn.Controls"
             mc:Ignorable="d" 
             Height="0" Width="0" WindowStyle="None" BorderThickness="0">
    <Grid>
            
    </Grid>
</Window>
View Code
using System;
using System.Windows;
using System.Windows.Threading;

namespace Controls
{
    /// <summary>
    /// AtuoCloseWindow.xaml 的交互逻辑
    /// </summary>
    public partial class AtuoCloseWindow : Window
    {
        DispatcherTimer dt { get; set; }
        public AtuoCloseWindow()
        {
            InitializeComponent();
            this.Loaded += AtuoCloseWindow_Loaded;
        }

        private void AtuoCloseWindow_Loaded(object sender, RoutedEventArgs e)
        {
            dt = new DispatcherTimer();
            dt.Interval = new TimeSpan(0, 0, 0, 0, 300);
            dt.Tick += Dt_Tick;
            dt.Start();
        }

        private void Dt_Tick(object sender, EventArgs e)
        {
            dt.Stop();
            this.Close();
        }
    }
}
View Code

复制代码

Microsoft.Office.Interop.PowerPoint.Presentation source = PPTapp.Presentations.Open(sourcePptFile, MsoTriState.msoFalse, MsoTriState.msoFalse, MsoTriState.msoFalse);
int sourceSlideRange = source.Slides.Count;

int forStart =  1 ;
int forEnd = sourceSlideRange ;
for (int i = forStart; i <= forEnd; ++i)
{
    Microsoft.Office.Interop.PowerPoint.Slide srcSlide = source.Slides[i];
    source.Slides[i].Copy();

    target.Slides.Paste(target.Slides.Count + 1);
    target.Slides[target.Slides.Count].FollowMasterBackground = MsoTriState.msoFalse;
    var win = new AtuoCloseWindow();
    win.Left = 0;
    win.Top = 0;
    win.ShowDialog();
}
View Code

 2、添加右键菜单

参考VSTO 为Office已有右键菜单添加自己的菜单项(word,Excel) (shuzhiduo.com)

CommandBarButton GKJDButton;
CommandBarButton RSJCButton;
CommandBarButton FXYJButton;
CommandBarButton RSJCButton1;
CommandBarButton ZXSCButton;
CommandBarButton NRJYButton;

private void AddRightMenu()
{
    CommandBar mzBar = Globals.ThisAddIn.Application.CommandBars["Text"];    //word文档已有的右键菜单Text
    CommandBarControls bars = mzBar.Controls;
    foreach (CommandBarControl temp_contrl in bars)
    {
        //如果已经存在就删除
        if (temp_contrl.Tag == contractFXYJ || temp_contrl.Tag == contractGKJD || temp_contrl.Tag == contractRSJC + "1")
        {
            temp_contrl.Delete();
        }
    }
    GKJDButton = bars.Add(MsoControlType.msoControlButton, Missing.Value, Missing.Value, Missing.Value, true) as CommandBarButton;
    if (GKJDButton != null)
    {
        //概括解读
        GKJDButton.Tag = contractGKJD;
        GKJDButton.BeginGroup = true;
        GKJDButton.Enabled = false;
        GKJDButton.Caption = contractGKJD;
        GKJDButton.Style = MsoButtonStyle.msoButtonIconAndCaption;
        GKJDButton.Click -= new _CommandBarButtonEvents_ClickEventHandler(ContractRightBtnCommand_Click);
        GKJDButton.Click += new _CommandBarButtonEvents_ClickEventHandler(ContractRightBtnCommand_Click);
    }
    RSJCButton = bars.Add(MsoControlType.msoControlButton, Missing.Value, Missing.Value, Missing.Value, true) as CommandBarButton;
    if (RSJCButton != null)
    {
        //润色纠错
        RSJCButton.Tag = contractRSJC + "1";
        RSJCButton.Caption = contractRSJC;
        RSJCButton.Enabled = false;
        RSJCButton.Style = MsoButtonStyle.msoButtonIconAndCaption;
        RSJCButton.Click -= new _CommandBarButtonEvents_ClickEventHandler(ContractRightBtnCommand_Click);
        RSJCButton.Click += new _CommandBarButtonEvents_ClickEventHandler(ContractRightBtnCommand_Click);
    }
    FXYJButton = bars.Add(MsoControlType.msoControlButton, Missing.Value, Missing.Value, Missing.Value, true) as CommandBarButton;
    if (FXYJButton != null)
    {
        //风险预警
        FXYJButton.Tag = contractFXYJ;
        FXYJButton.Caption = contractFXYJ;
        FXYJButton.Enabled = false;
        FXYJButton.Style = MsoButtonStyle.msoButtonIconAndCaption;
        FXYJButton.Click -= new _CommandBarButtonEvents_ClickEventHandler(ContractRightBtnCommand_Click);
        FXYJButton.Click += new _CommandBarButtonEvents_ClickEventHandler(ContractRightBtnCommand_Click);
    }
}
View Code

3、TextBox无法粘贴回车

WPF编程,TextBox回车换行的一种方法 (xjx100.cn)

往TextBox复制文本时,若文本有回车,回车后面的文本会无法复制。

解决办法:将TextBox的AcceptsReturn属性设置设为True,

将 TextWrapping 属性设置为 Wrap 会导致输入的文本在到达 TextBox 控件的边缘时换至新行,必要时会自动扩展
TextBox 控件以便为新行留出空间。


将 AcceptsReturn 属性设置为 true 会导致在按 Return 键时插入新行,必要时会再次自动扩展 TextBox
以便为新行留出空间。
View Code

 

posted @ 2023-06-15 20:19  六镇2012  阅读(337)  评论(0编辑  收藏  举报