I have implemented a hyperlink interface; when the user selects text in the document and then clicks a button from my Word Add-in, there is a comment box that is pre-filled with text added to this selection.
However, I want to include a hyperlink that is clickable to bring the user to a Google Doc and this link should be at the end of the comment box. This is what I have tried so far:
Hyperlink link = new Link();
link.Address = (String) oAddress;
link.SubAddress = (String) oSubAddress;
link.TextToDisplay = "more";
selection.Comments.Add(rng2, comment + link)
It looks like you need to create a collection of Hyperlinks from your current document, then add your hyperlink to it.
Below code should highlight everything inside your comment.
// Select the element you want to apply the hyperlink to - you will have to use the Find method
Microsoft.Office.Interop.Word.Range currentRange = myDoc.Comments[0].Range
if (currentRange != null)
{
Microsoft.Office.Interop.Word.Hyperlink hp = (Microsoft.Office.Interop.Word.Hyperlink)
// This line is what you are missing
currentRange.Hyperlinks.Add(currentRange, "http://www.microsoft.com");
}
Credit to https://stackoverflow.com/a/8665770/5209435.
You can use the above as a base before using the Find method to narrow to find the text that you want to hyperlink and just apply it to the selected text. See this question.
Related
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.
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();
}
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();
I've been searching for this for hours, but could not find appropriate approach to do so. On MSDN, they suggest using Address and SubAddress to locate a slide in a Presentation, but this failed its purpose.
So my question is, how to add a hyperlink to a slide in the same Presentation?
Finally I've figured it out, and since there's lack of resources, I would like to post my solution.
Interestingly, to add a hyperlink to a slide inside the same presentation, you need to leave Address property blank, and set its SubAddress to be a string in a format: "yourSlideID,yourSlideIndex,yourSlideName".
For example, you want to add a hyperlink to a slide with slide ID 256, slide index 1, slide name "Slide 1", to a shape, do this:
var mouseOnClickAction = shape.ActionSettings[PpMouseActivation.ppMouseClick];
mouseOnClickAction.Action = PpActionType.ppActionNamedSlideShow;
mouseOnClickAction.Hyperlink.Address = null;
mouseOnClickAction.Hyperlink.SubAddress = "256,1,Slide 1";
Hope this helps everybody :D
I am making an asp.net web application which has to play videos. In my start page I have a hyperlink for each video. All the hyperlinks are identical, except their names. This Means they all link to the same page. Im interrested in knowing wether there is an option to know which hyperlink was clicked. I would like to retrieve the name of the hyperlink.
My code for generating the hyperlinks looks as follows:
foreach (FileInfo i in corFiles)
{
HyperLink t = new HyperLink();
t.Text = i.Name;
t.NavigateUrl = "page.aspx";
CorrectArray.Add(t);
}
return CorrectArray;
The text of the hyperlink is Unique to a video, which Means I can change the src destination of the video to play based on the text name. So the question goes as follows. Are there any way of retrieving the text name of the hyperlink when it is clicked by the user?
I hope you can help! Thanks in advance.
Regards
Magnus
You can add a link buttons instead of hyper links, if you want to make a post back to the same page.
foreach (FileInfo i in corFiles)
{
LinkButton t = new LinkButton();
t.Text = i.Name;
t.Click += new EventHandler(DynamicClick);
t.CommandName = i.Name;
CorrectArray.Add(t);
}
void DynamicCommand(Object sender, CommandEventArgs e)
{
// using e.CommandName and e.CommandArgument you can differentiate the hyperlinks
}
If i understood your question,
you have to add the name attribute in the hyperlink tag and get its values in the code behind by fetching names
You can use JQuery that is integrated into .NET to get the text of the hyperlink upon it is clicked by the user. To be able to access the Hyperlink's text from Javascript simply add it to a custon tag inside the link to have something like this <a href="page.aspx" htext="hyperlink text">. As the hyperlink html is generated from .NET server side code you have to generate this custom tag from the .NET server side context.
Why don't you use a Querystring?
t.NavigateUrl = "page.aspx?video=<someid>"
and in the page you parse the querystring to show the correct video?