Get rich text box from server - c#

I have a Word 2010 add-in that pulls certain information from the server and displays it in Word within a bookmark. One is the "Rich Text Content Control" found in the Developer tab. Is there a way to "get" it programmatically so I can manipulate it? I am using this method to do something similar for getting a table that is also put in Word by the server:
private Table GetTableByBookmarkName(Bookmark bookmark, int i)
{
Table tbl = bookmark.Range.Tables[i];
if (tbl != null)
{
return tbl;
}
else
{
return null;
}
}

I undertand your question is that you want to get a reference to a RichText content control, directly (as opposed to using a bookmark). Yes, this is possible.
Use an Index value (1-based!) for the Collection (order in the document): Document.ContentControls[index]
Use the Document.SelectContentControlsByTag method to return a collection of content controls having the same value in the Tag property
Use the Document.SelectContentControlsByTitle method to return a collection of content controls having the same value in the Title property.
Similarly to bookmarks, a Title and/or a Tag can be assigned to a content control when the document/template is being designed. There's a "Properties" button in the Developer tab, in the same group as the content controls.
Unlike bookmarks, more than one content control can have the same Title / Tag, which is why a collection is returned.

Related

.NET WPF WebBrowser Control: Insert HTML at ControlRange selection

I have a WebBrowser control that I am using to create an HTML editor, and I need to be able to insert a string of HTML at the current selection in the document.
Generally, I can do something like this to paste HTML at the current selection, if the selection is a text selection:
IHTMLSelectionObject selection = webBrowser.Document.DomDocument.selection;
// Assume that selection.type == "Text"
IHTMLTxtRange textRange = selection.createRange() as IHTMLTxtRange;
textRange.pasteHTML(myHtmlString);
However, if the current selection is a ControlRange selection, there doesn't seem to be any direct way to insert/paste HTML at that position.
For example:
// Assume that selection.type == "Control"
IHTMLControlRange ctrlRange = selection.createRange() as IHTMLControlRange;
// This throws an error, as IHTMLControlRange has no pasteHTML method
ctrlRange.pasteHTML(myHtmlString);
I know that I can use the HtmlElement.InsertAdjacentElement method to insert an element before or after another element, but that is very limiting, as sometimes I need to be able to insert raw HTML, rather than needing to create an HtmlElement object for it first.
Is there any way to be able to paste/insert an HTML string at the caret position, or over a ControlRange selection?
I have found a workaround for this problem, at least for my specific use case.
The IHTMLSelectionObject.createRange() method returns dynamic, but it will resolve to either an IHTMLTxtRange or an IHTMLControlRange, depending on what the selection type is.
If selection.type == "Text" or selection.type == "None", it returns an IHTMLTxtRange, and if selection.type == "Control", it returns an IHTMLControlRange.
The following statement works for empty selections and text selections:
DomDocument.selection.createRange().pasteHTML(myHtml);
However, in the case of pasting over a control selection, the above statement won't work by default because the createRange() method will return an IHTMLControlRange, which, as mentioned above, has no createRange() method. However, we would be wanting to overwrite the current selection with the new HTML anyway, so one could assume that it is safe to just clear the selection (delete it) and then paste the HTML at the newly empty selection.
Solution
Something like this should work for all types of selections:
// If we have a control selection, clear the selection
if (DomDocument.selection.type == "Control")
DomDocument.selection.clear();
// Now it is no longer a control selection, but an empty text selection
DomDocument.selection.createRange().pasteHTML(myHtml);
This does feel a bit hacky, but it solves the problem for me.

Retrieve hidden text blocks and replace all content between two of them

I want to use OpenXML to automate Word document creation by taking a given document as a template. This template contains text blocks with a special syntax (namely e.g. «tagname[»...«]tagname») in the form of hidden text (in the font dialog box, the 'Hidden' checkbox in the effects section is activated) so that they don't show up when the document is printed.
Depending on the tagname I want to replace any content which might be already there in the template file between the opening and closing tag with some other content (e.g. in «today[»01/01/2000«]today» the content 01/01/2000 would be substituted with 07/06/2018) preferably preserving the format (e.g. bold, italic or text color).
How can I retrieve the hidden text parts and is there an easy way to replace anything between corresponding tags using C#?
I am not sure what exactly are the text blocks in your template. Instead you can use Content Control from Developer options at the required place, then you can name them from the properties of content control.
today will be name of the Content Control
Once you have all the content control at your template, you can look for specific content control with name and add the new value you want to.
Here is the Snippet to give you an idea.
// Title is name of content control(today), value is what you want to add(1/01/2000)
private static void UpdateControl(WordprocessingDocument document, string title, string value)
{
MainDocumentPart mainPart = document.MainDocumentPart;
var sdtRuns = mainPart.Document.Descendants<SdtRun>()
.Where(run => run.SdtProperties.GetFirstChild<Tag>().Val.Value == title);
foreach (SdtRun sdtRun in sdtRuns)
{
sdtRun.Descendants<Text>().First().Text = value;
}
document.MainDocumentPart.Document.Save();
}

VSTO Word Add-in - insert Content Control around selected text

I'm trying to add a rich text content control around the user's selected text in a Word document.
I'm new to VSTO and Content Controls so i'm using the MSDN examples as a baseline. The example shows this, which adds the Content Control at the chosen position:
private void AddRichTextControlAtSelection()
{
word.Document currentDocument = Globals.ThisAddIn.Application.ActiveDocument;
currentDocument.Paragraphs[1].Range.InsertParagraphBefore();
currentDocument.Paragraphs[1].Range.Select();
Document extendedDocument = Globals.Factory.GetVstoObject(currentDocument);
richTextControl1 = extendedDocument.Controls.AddRichTextContentControl("richTextControl1");
richTextControl1.PlaceholderText = "Enter your first name";
}
However i want the Content Control to wrap around the user's selected text. Any help, please?
What you found is one possibility. More efficient and "cleaner" (IMO) would be to use the constructor that accepts a RANGE object and pass the Range. If you want the user's selection then
richTextControl1 = extendedDocument.Controls.AddRichTextContentControl(extendedDocument.Parent.Selection.Range, "richTextControl1");
//the Parent of a Document is the Word.Application
//Selection is a dependent of the Word.Application
Otherwise, building on your code sample:
richTextControl1 = extendedDocument.Controls.AddRichTextContentControl(currentDocument.Paragraphs[1].Range, "richTextControl1");
Note that if you don't need to work with VSTO's extensions of the Content Controls you don't need to go through the GlobalFactory steps, you can simply insert the "interop" versions of the Content Controls.
Simple fix in the end: currentDocument.ActiveWindow.Selection.Range.Select();

Find Content Control by TagName in Word document in OpenXml

I am attempting to insert text in to a content control in my word document template using OpenXml. First I search the content control by its tag name and then adding paragraph element in the SdtBlock like below,
SdtBlock contentBlock = wordDoc.MainDocumentPart.Document.Body.Descendants<SdtBlock>()
.Where(r => r.SdtProperties.GetFirstChild<Tag>().Val == "AssessmentSection")
.Single();
But when I execute this statement, I am getting "Object reference not set to an instance of an object." error message. The template document already has another content control and I was able to find that control using the same above statement with only tagname as different. But after adding "AssessmentSection" content control in template and while running the program, I get "Object Reference..." error for "AssessmentSection" control and the program fails. I am sure the new content control tag name and title are unique with other content control.
Can someone please help me why this strange behaviour is occurring and how to fix it???
you also could loop the documents ContentControls items and check their tags, like:
foreach (Word.ContentControl contentcontrol in wordDoc.ContentControls)
{
if (contentcontrol.Tag != null)
{
...
}
}

How can I grab a textfield value in Ext.Net?

I know there's a lot of information on this, but mine doesn't seem to be working out so well. I have a form that's created in C# in a form panel. My textfields are created like below:
Ext.Net.Panel panel = new Ext.Net.Panel();
Field field = null;
field = new TextField();
field.Name = "FieldTitle";
field.ID = "FieldID";
panel.Add(field);
this.searchform.Add(panel);
this.searchform.Add(new Ext.Net.Button()
{
Text = "Search",
Handler = "getID();"
});
When the search button is hit, then a JavaScript function is called which performs a store reload:
Ext.getCmp("#Gridpanel").getStore().reload({});
On the reload, I want to read the form fields and use the text for another part of the code. However, the below code doesn't seem to be working:
if(X.isAjaxRequest){
var ctrl = X.GetCmp<TextField>("FieldID");
string value = ctrl.Value.ToString();
}
I can get inside the 'if' statement, but ctrl comes back as null. Is there something else I need to include to grab the text field data?
EDIT
So I'm realizing that I'll have to pass an array of the search field ID's to a JavaScript function, then send a dataset back to the server side in order to implement the search. Just to throw it out there, is there a way to dynamically create controls (ie; a TextField) in C# and then get the value from those controls after an event is fired (ie; a button click)?
You can try to get the textfield using
Ext.getCmp("#FieldID") or X.getCmp("#FieldID"). FieldID is the client ID for TextField.
Use developer Tools to check the ID for the TextField

Categories

Resources