public string GetTooltip(MarkerContext ctx) { // A MarkerContext object contains state describing a text editor instance of a link definition. // GetTooltip gets called when the mouse cursor hovers over plugin-associated link text. // It is possible that any member of ctx may be null, string.Empty or 0. // The returned string can be either plane text or XAML. // XAML text must be valid in the context of the VASourceLinks.dll assembly, thus all // resources must be defined in a way which the XAML parser may resolve. // Return null or String.Empty if you don't need to provide tooltip text from your plugin. Debug.WriteLine("Source Links calling GetTooltip(MarkerContext)"); // We can determine the link definition behavior from the MarkerContext. // When Exe != null, then behavior is set to ShellExecute. // When Url != null, then behavior is set to open URL in Browser. // The Url, Exe and ExeArgs members of the MarkerContext contain information // from the link definition; if your plugin overrides URL or Execute, the values // may be irrelevant. // Note: In this example, GetUrl is always called because Flags include // OverrideUrl; user can't select ShellExecute behavior with the default // implementation of the example plugin. string actionText = string.Empty; string actionLabel = string.Empty; if (Flags.HasFlag(PluginFlags.OverrideExecute)) { actionLabel = "Execute:"; actionText = "Overridden by plugin"; } else if (Flags.HasFlag(PluginFlags.OverrideUrl)) { actionLabel = "Open URL:"; actionText = GetUrl(ctx); } else { if (ctx.Url != null) // Open URL in Browser { actionLabel = "Open URL:"; actionText = ctx.Url; } else if (ctx.Exe != null) // ShellExecute { actionLabel = "ShellExecute:"; actionText = ctx.Exe; if (!string.IsNullOrEmpty(ctx.ExeArgs)) { actionText += " " + ctx.ExeArgs; } } } // The return string can be either plain text or valid XAML. // This example demonstrates how to turn simple markup into valid XAML. // The returned XAML defines a TextBlock. string tooltip = string.Format( // We can use formatted markup text for FlowDocument. // See: https://msdn.microsoft.com/en-us/library/aa970909(v=vs.110).aspx and // https://docs.microsoft.com/en-us/dotnet/articles/framework/wpf/advanced/flow-document-overview "<Bold>File name:</Bold> {0}<LineBreak/>" + "<Bold>Project file name:</Bold> {1}<LineBreak/>" + "<Bold>Solution file name:</Bold> {2}<LineBreak/>" + "<Bold>Line:</Bold> {3}<LineBreak/>" + "<Bold>Column:</Bold> {4}<LineBreak/>" + "<Bold>Line text:</Bold> {5}<LineBreak/>" + "<Bold>Marker text:</Bold> {6}<LineBreak/>" + // Or we can use some HTML inline tags: H1-H6, B, STRONG, I, EM, U, DEL, INS, S, BR // Those tags are replaced with appropriate XAML tags by calling PluginUtils.WrapMarkupInXAML. // HTML attributes are not supported. "<b>Keyword text:</b> {7}<br/>" + "<b>Value text:</b> {8}<br/>" + "<b>" + actionLabel + "</b> {9}", // Images are supported: // "<Image Source=\"path\\to\\image.jpg\"/>" // Use PluginUtils.EncodeXML in places where text could contain special XML characters. PluginUtils.EncodeXML(System.IO.Path.GetFileName(ctx.FileName)), // 0 PluginUtils.EncodeXML(System.IO.Path.GetFileName(ctx.ProjectName)), // 1 PluginUtils.EncodeXML(System.IO.Path.GetFileName(ctx.SolutionName)), // 2 ctx.Line, // 3 ctx.Column, // 4 PluginUtils.EncodeXML(ctx.LineText), // 5 PluginUtils.EncodeXML(ctx.MarkerText), // 6 PluginUtils.EncodeXML(ctx.KeywordText), // 7 PluginUtils.EncodeXML(ctx.ValueText), // 8 PluginUtils.EncodeXML(actionText)); // 9 // PluginUtils.WrapMarkupInXAML replaces selected HTML formatting tags // with appropriate XAML tags (<b> becomes <Bold> and <br> becomes // <LineBreak>) and wraps the result into a TextBlock. // Note: Because WrapMarkupInXAML wraps your input into a TextBlock, it // can contain ONLY tags derived from Inline. If your tooltip must contain // Block, then don't use this method; format the whole XAML directly, // including required namespaces. return(PluginUtils.WrapMarkupInXAML(tooltip)); }