document.SelectSingleNode("//NS0:region/@NS0:tax", _
Constants.DOCUMENT_NAMESPACE_WITH_PREFIX).NodeValue
Now, you can make a call to this method whenever the user changes the region or item. However, what if the user wants to enter the quantity? You could either provide an option in the document actions pane to recalculate the price or use a command bar button to force recalculation. It's useful to view the XML content, after saving the document as XML with "save data only". You can easily submit or save the XML-only content to appropriate repositories or database files to repurpose later.
Protecting Documents
In some cases, you need to control what areas users can edit. To do this you
protect your document with a password during the design stage. At runtime, you programmatically determine the sections of the document to unlock using Editors. This way, you can maintain a lock on the document while still allowing users to edit in specific sections.
Consider the situation where you want to lock certain sections of a sample document allowing editing only within the table, for example. For the sample document, the password is "word." First, here's the procedure to lock an entire document:
- Right click on the document and click open.
- In the tools menu select "Protect document".
- The task pane will show an "Editing restrictions" section, select the checkbox and click the "Yes, Start Enforcing Protection" button.
- You'll get a modal dialog in which to enter a password. For this example, enter "word" as the password, save the template and close it.
If you now reopen the template you'll find you aren't allowed to edit anywhere in the document. You can't even edit the document programmatically. Fortunately, you can restrict or allow editing using two shared methods in Utils called
ProtectDocument and
UnProtectDocument.
Public Const PASSWORD As String = "word"
Public Shared Sub ProtectDocument()
If document.ProtectionType = _
Word.WdProtectionType.wdNoProtection Then
document.Protect( _
Word.WdProtectionType.wdAllowOnlyReading, , _
Constants.PASSWORD)
End If
End Sub
Public Shared Sub UnProtectDocument()
If document.ProtectionType = _
Word.WdProtectionType.wdAllowOnlyReading Then
document.Unprotect(Constants.PASSWORD)
End If
End Sub
Protect checks if the document ProtectionType is
wdNoProtection; if so, it protects the document with a read-only option for users.
UnProtectDocument does the exact opposite and unprotects the document completely. Now you can make a call to
Protect wherever you want to restrict editing of the XML nodes in the document and call
UnProtectDocument whenever you want to allow editing. Consider the
Invoke method in the
item class implementation:
Try
DocumentUtils.UnProtectDocument()
Dim rangeNode As Word.XMLNode = _
CType(Target, Word.Range).XMLNodes(1)
...
Finally
DocumentUtils.ProtectDocument()
End Try
To implement this, you need to ensure that under no circumstances can a deadlock occur after unprotecting the document. The
Try/Finally block achieves this by calling
ProtectDocument in the
Finally block as shown above. You can test this code by running the application. You'll find that you can populate the
itemname node via document actions but you won't be able to edit the node contents manually.
To ensure that specific nodes are editable you need to use editors. For example, suppose you want to let the user enter only
quantity while populating other nodes via the document actions pane. You need to get a reference to the
quantity XMLNode's range, and add an editor to it. The following line adds an editor set to
wdEditorEveryone meaning anyone can edit the node. In the sample document the
priceNode's next sibling is the
quantity node, therefore, you need to retrieve the range for that and add the editor.
priceNode.NextSibling.Range.Editors.Add( _
Word.WdEditorType.wdEditorEveryone)
Run the document again. After adding the editor you'll see colored opening and closing square brackets within the quantity XMLNode. Word displays the brackets to indicate that the area within the brackets is editable. You can now alter the quantity manually. Now you just need to implement the protect/unprotect scheme in all the places where you want programmatic editing to add/remove the XML elements/attributes.