首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >按钮保存在word VSTO中。

按钮保存在word VSTO中。
EN

Stack Overflow用户
提问于 2021-05-04 08:37:37
回答 1查看 178关注 0票数 0

我有一段代码:

代码语言:javascript
运行
复制
private void button2_Click(object sender, RibbonControlEventArgs e)
{
    Microsoft.Office.Tools.Word.Controls.Button salesButton;
    Document vstodoc = Globals.Factory.GetVstoObject(Globals.ThisAddIn.Application.ActiveDocument);
    Microsoft.Office.Interop.Word.Application objApplication = Globals.ThisAddIn.Application;
    Microsoft.Office.Interop.Word.Selection objSelection = objApplication.Selection;
    Microsoft.Office.Interop.Word.Range objRange = objSelection.Range;
    salesButton = vstodoc.Controls.AddButton(objRange, 20, 20, "salesButton");
    salesButton.Text = "Calculate Total Sales";
}

当我点击按钮时,一个按钮被插入到Word文档中,但是当我保存它并尝试重新打开word文档时,按钮就不再存在了。

保存Word文档之前的

保存Word文档后的

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-06-01 03:18:13

我找到了解决这个问题的办法。

1。所有动态创建的主机控件都与其事件断开连接,并失去数据绑定功能。您可以向解决方案中添加代码,以便在文档重新打开(动态MsControl)时重新创建主机控件。

步骤1创建一个word-addsin

步骤2将引用添加到

Microsoft.Office.Tools.Word.v4.0.Utilities.dll

步骤3向项目添加一个带

  • 现在,您的项目应该如下所示

步骤4转到ThisAddsIn.cs文件

代码语言:javascript
运行
复制
 public partial class ThisAddIn
    {
 
        private void ThisAddIn_Startup(object sender, System.EventArgs e)
        {
        }

        private void ThisAddIn_Shutdown(object sender, System.EventArgs e)
        {
        }

        #region VSTO generated code

        /// <summary>
        /// Required method for Designer support - do not modify
        /// the contents of this method with the code editor.
        /// </summary>
        private void InternalStartup()
        {
            this.Startup += new System.EventHandler(ThisAddIn_Startup);
            this.Shutdown += new System.EventHandler(ThisAddIn_Shutdown);
        }
        
        #endregion
    }

在上面的类名it WhenRibionBtnIsClicked()中创建一个新方法

代码语言:javascript
运行
复制
  private Microsoft.Office.Tools.Word.Controls.Button button = null;//decalre a global varible
  internal void WhenRibionBtnIsClicked()
  {
    Document vstoDocument = Globals.Factory.GetVstoObject(this.Application.ActiveDocument);
    Word.Selection selection = this.Application.Selection;
    if (selection != null && selection.Range != null)
    {
      string name ="myBtn";
      Button button = new Button();
      button.Click += new EventHandler(Generatedbtn_Click);
      button = vstoDocument.Controls.AddButton(selection.Range, 100, 30, name);
     
      button.Text = "I am A Generated Button";
      button.Name = name;
     
     /*this part is done so that when the document is closed the button state is saved in the document property*/
      string startPosition = selection.Range.Start.ToString();
      string endPosition = selection.Range.End.ToString();
      //create a custom property to save infornmation needed to recreate the button
    Microsoft.Office.Core.DocumentProperties properties =(DocumentProperties)Globals.ThisAddIn.Application.ActiveDocument.CustomDocumentProperties;

//save the start range pos
   if (properties.Cast<DocumentProperty>().Where(c => c.Name == "startPosition").Count() == 0)
    {
      properties.Add("startPosition", false, MsoDocProperties.msoPropertyTypeString, startPosition);
    }
    else{
          properties["startPosition"].Value = startPosition;
          Globals.ThisAddIn.Application.ActiveDocument.Saved = false; //important somtimes
        }

      //save the End range pos
   if (properties.Cast<DocumentProperty>().Where(c => c.Name == "endPosition").Count() == 0)
   {
     properties.Add("endPosition", false, MsoDocProperties.msoPropertyTypeString, endPosition);
   }else
       {
         properties["endPosition"].Value = endPosition;
         Globals.ThisAddIn.Application.ActiveDocument.Saved = false; //important somtimes
       }
   // Store Button Info
   if (properties.Cast<DocumentProperty>().Where(c => c.Name == "btnName").Count() == 0)
     {
      properties.Add("btnName", false, MsoDocProperties.msoPropertyTypeString, name);
     } else
            {
               properties["btnName"].Value = startPosition;
               Globals.ThisAddIn.Application.ActiveDocument.Saved = false; //important somtimes
            }

  if (properties.Cast<DocumentProperty>().Where(c => c.Name == "btnText").Count() == 0)
  {
    properties.Add("btnText", false, MsoDocProperties.msoPropertyTypeString, "I am A Generated Button");
  }else
      {
        properties["btnText"].Value = "I am A Generated Button";
        Globals.ThisAddIn.Application.ActiveDocument.Saved = false; //important somtimes                    
      }
   //you can add more custom properties just like how i added start and end strings
    }//end of if selection != null && selection.Range != null

  }//end of WhenRibionBtnIsClicked Method

步骤5为word文件中生成的按钮创建按钮单击事件

代码语言:javascript
运行
复制
 void Generatedbtn_Click(object sender, EventArgs e)
 {
    MessageBox.Show("I have Been Clicked :-O");
 }

步骤6,现在在Ribbon.cs文件中获取在带状中创建的按钮的单击事件,并将其指向上面创建的类

代码语言:javascript
运行
复制
  private void btnTest_Click(object sender, RibbonControlEventArgs e)
        {
            Globals.ThisAddIn.WhenRibionBtnIsClicked();
        }

因此,现在运行它时,您应该能够看到以下内容:

然而,在这之后,您将面临的问题是,当您保存文档时,这些东西被移除,所以您必须做的是在单词启动时重新创建这个按钮,并使用您存储的属性获取按钮状态或其他有关按钮的信息。

步骤7转到函数ThisAddIn_Startup

代码语言:javascript
运行
复制
private void ThisAddIn_Startup(object sender, System.EventArgs e)
{
  Word.Application wb;
  wb = this.Application;
  if (wb.Documents.Count > 0)
   {
      String queryResult_StartPosition = String.Empty;
      String queryResult_EndPosition = String.Empty;
      String queryResult_btnName = String.Empty;
      String queryResult_btnText = String.Empty;
      Microsoft.Office.Core.DocumentProperties properties = (DocumentProperties)Globals.ThisAddIn.Application.ActiveDocument.CustomDocumentProperties;

     //get doc info about start pos
     if (properties.Cast<DocumentProperty>().Where(c => c.Name == "startPosition").Count() > 0)
    {
        queryResult_StartPosition = properties["startPosition"].Value;
    }
    else
       {
         queryResult_StartPosition = String.Empty;
       }
       //get doc info about end pos
                
    if (properties.Cast<DocumentProperty>().Where(c => c.Name == "endPosition").Count() > 0)
  {
    queryResult_EndPosition = properties["endPosition"].Value;
  }
   else
       {
         queryResult_EndPosition = String.Empty;
       }
   //get info about btn name
    if (properties.Cast<DocumentProperty>().Where(c => c.Name == "btnName").Count() > 0)
     {
       queryResult_btnName = properties["btnName"].Value;
     }
      else
         {
           queryResult_btnName = String.Empty;
         }
      //get info about btn text
 if (properties.Cast<DocumentProperty>().Where(c => c.Name == "issue_title").Count() > 0)
 {
   queryResult_btnText = properties["btnText"].Value;
 }
   else
   {
     queryResult_btnText = String.Empty;
   }

 Document vstoDocument = Globals.Factory.GetVstoObject(this.Application.ActiveDocument);
 Word.Range rng = vstoDocument.Range(queryResult_StartPosition, queryResult_EndPosition); 
 Word.Selection selection = this.Application.Selection;
 if (selection != null && rng != null)
 {
   Button button = new Button();
   button.Click += new EventHandler(Generatedbtn_Click);
   button = vstoDocument.Controls.AddButton(rng, 100, 30, queryResult_btnName);
   button.Text = queryResult_btnText;
 }
}//end of wb.Documents
 
}//end of ThisAddIn_Startup

上面的代码应该能够从您创建的自定义属性中获取所有信息,并重新创建按钮。如果由于某种原因,在启动文档时,adds-in选项卡没有出现在word中,这意味着您的ThisAddIn_Startup函数-to调试中有错误,请尝试将ThisAddIn_Startup函数中的所有内容放入一个单独的按钮中,然后测试并查看错误代码。请注意:您可以在普通的C#表单(打开表单、关闭表单、读取文本文件等)中做任何您想做的事情。

我在github中提供了一个示例,其中有一个可以检查的调试按钮

持久化动态控制

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/67381389

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档