none
How to remove a content control once Custom XML is populated programatically RRS feed

  • Question

  • I have a document that I use as a template that has a bunch of custom controls in it. Each control has an XPath that links it to an element in the custom XML. I have a simple program for inserting a new custom xml file into the document.

    Now i want to remove the content controls so that the document recipient doesn't see them but leave the text intact.

    This should be simple...Right?

    Thanks,
    Don Rule

    Friday, December 30, 2011 12:59 AM

Answers

  • Hi Don

    I've done some quick testing for you and the following appears to work. But it's possible the approach has some weaknesses that a quick test doesn't bring to light.

    My test is with VBA, but the principle should carry over to other languages. I set up events for the Enter and Exit events for the content controls in the document, as well as a variables "at the class level".

    On entering a content control the ContentControl object passed by the event arg is assigned to the class level variable if the content control contains content and that content is not the placeholder text. When focus enters any other content control, if the variable is not Nothing (null) then that content control is deleted and the variable set to Nothing (null).

    As I said, this was a quick test. You could also check the content of the CustomXMLPart, rather than the text in the content control, for example.

    Rather than using ContentControlOnEnter you could use the WindowSelectionChange event at the application level. That would allow for doing the test if the user is allowed to work in other places in the document than just content controls.

    For fairly obvious logical reasons it's not possible for you to delete the content control that triggers the Exit event as the control has to continue to exist during the duration of the event. (As a matter of fact, that's why you generally can't affect the triggering content control during an event.)

    Private ccDone As Word.ContentControl
    
    Private Sub Document_ContentControlOnEnter(ByVal ContentControl As ContentControl)
        If Not ccDone Is Nothing Then
            Debug.Print ccDone.Title
            ccDone.Delete
            Set ccDone = Nothing
        End If
    End Sub
    
    Private Sub Document_ContentControlOnExit(ByVal ContentControl As ContentControl, Cancel As Boolean)
        'Debug.Print Len(ContentControl.Range.Text), ContentControl.Range.Text, ContentControl.PlaceholderText
        If Len(ContentControl.Range.Text) > 0 And (ContentControl.Range.Text <> ContentControl.PlaceholderText) Then
            Set ccDone = ContentControl
        Else
            Set ccDone = Nothing
        End If
    Debug.Print ccDone Is Nothing
    End Sub
    
    


     


    Cindy Meister, VSTO/Word MVP
    Saturday, December 31, 2011 10:13 AM
    Moderator

All replies

  • Hi Don

    I've done some quick testing for you and the following appears to work. But it's possible the approach has some weaknesses that a quick test doesn't bring to light.

    My test is with VBA, but the principle should carry over to other languages. I set up events for the Enter and Exit events for the content controls in the document, as well as a variables "at the class level".

    On entering a content control the ContentControl object passed by the event arg is assigned to the class level variable if the content control contains content and that content is not the placeholder text. When focus enters any other content control, if the variable is not Nothing (null) then that content control is deleted and the variable set to Nothing (null).

    As I said, this was a quick test. You could also check the content of the CustomXMLPart, rather than the text in the content control, for example.

    Rather than using ContentControlOnEnter you could use the WindowSelectionChange event at the application level. That would allow for doing the test if the user is allowed to work in other places in the document than just content controls.

    For fairly obvious logical reasons it's not possible for you to delete the content control that triggers the Exit event as the control has to continue to exist during the duration of the event. (As a matter of fact, that's why you generally can't affect the triggering content control during an event.)

    Private ccDone As Word.ContentControl
    
    Private Sub Document_ContentControlOnEnter(ByVal ContentControl As ContentControl)
        If Not ccDone Is Nothing Then
            Debug.Print ccDone.Title
            ccDone.Delete
            Set ccDone = Nothing
        End If
    End Sub
    
    Private Sub Document_ContentControlOnExit(ByVal ContentControl As ContentControl, Cancel As Boolean)
        'Debug.Print Len(ContentControl.Range.Text), ContentControl.Range.Text, ContentControl.PlaceholderText
        If Len(ContentControl.Range.Text) > 0 And (ContentControl.Range.Text <> ContentControl.PlaceholderText) Then
            Set ccDone = ContentControl
        Else
            Set ccDone = Nothing
        End If
    Debug.Print ccDone Is Nothing
    End Sub
    
    


     


    Cindy Meister, VSTO/Word MVP
    Saturday, December 31, 2011 10:13 AM
    Moderator
  • Hi Cindy

    Nice and fast solution, but can it be done by using OpenXML SDK, without actually using Word application?

     

    Thank you

    Mahyar

    Friday, February 3, 2012 1:44 AM
  • Hi Mahyar

    It would certainly be possible, but I can't give you any code right off-hand and the question is off-topic in this forum (which specializes in the Word API) in any case.

    You should ask on OpenXMLDeveloper.org or in the Open XML SDK forum (http://social.msdn.microsoft.com/forums/en-US/oxmlsdk/threads/) on MSDN.


    Cindy Meister, VSTO/Word MVP
    Friday, February 3, 2012 3:30 PM
    Moderator