/// <summary>
        /// This is used to get the content to add to the quick info by looking up the given topic ID to get its
        /// title and filename if possible.
        /// </summary>
        /// <param name="elementName">The element name for which to create content</param>
        /// <param name="id">The ID to look up if necessary</param>
        /// <returns>The content to add to the quick info (a text block element containing the additional info
        /// about the element)</returns>
        private UIElement CreateInfoText(string elementName, string id)
        {
            if(String.IsNullOrWhiteSpace(elementName) || String.IsNullOrWhiteSpace(id))
                return null;

            var textBlock = new TextBlock();

            switch(elementName)
            {
                case "conceptualLink":
                    var projectFileSearcher = new ProjectFileSearcher(serviceProvider, null);
                    string title, filename, relativePath;

                    bool found = projectFileSearcher.GetInfoFor(ProjectFileSearcher.IdType.Link, id,
                        out title, out filename, out relativePath);

                    textBlock.Inlines.AddRange(new Inline[] {
                        new Bold(new Run("Title: ")),
                        new Run(title),
                        new LineBreak(),
                        new Bold(new Run("Filename: ")),
                        new Run(relativePath)
                    });

                    if(found && ctrlClickEnabled)
                        textBlock.Inlines.AddRange(new Inline[] {
                            new LineBreak(),
                            new Run("Ctrl+Click to open the file")
                        });
                    break;

                case "cref":
                    if(!ctrlClickEnabled)
                        return null;

                    if(!IntelliSense.RoslynHacks.RoslynUtilities.IsFinalRoslyn)
                        textBlock.Inlines.Add(new Run("Ctrl+Click to go to definition (within solution only)"));
                    else
                        textBlock.Inlines.Add(new Run("Ctrl+Click to go to definition"));
                    break;

                default:
                    if(!ctrlClickEnabled)
                        return null;

                    textBlock.Inlines.Add(new Run("Ctrl+Click to open the containing file"));
                    break;
            }

            // Set the styles in order to support other themes
            textBlock.SetResourceReference(TextBlock.BackgroundProperty, EnvironmentColors.ToolTipBrushKey);
            textBlock.SetResourceReference(TextBlock.ForegroundProperty, EnvironmentColors.ToolTipTextBrushKey);

            return textBlock;
        }
        /// <summary>
        /// This is used to get the content to add to the quick info by looking up the given topic ID to get its
        /// title and filename if possible.
        /// </summary>
        /// <param name="elementName">The element name for which to create content</param>
        /// <param name="id">The ID to look up if necessary</param>
        /// <returns>The content to add to the quick info (a text block element containing the additional info
        /// about the element)</returns>
        private UIElement CreateInfoText(string elementName, string id)
        {
            if (String.IsNullOrWhiteSpace(elementName) || String.IsNullOrWhiteSpace(id))
            {
                return(null);
            }

            var textBlock = new TextBlock();

            switch (elementName)
            {
            case "conceptualLink":
                var    projectFileSearcher = new ProjectFileSearcher(serviceProvider, null);
                string title, filename, relativePath;

#pragma warning disable VSTHRD010
                bool found = projectFileSearcher.GetInfoFor(ProjectFileSearcher.IdType.Link, id,
                                                            out title, out filename, out relativePath);
#pragma warning restore VSTHRD010

                textBlock.Inlines.AddRange(new Inline[] {
                    new Bold(new Run("Title: ")),
                    new Run(title),
                    new LineBreak(),
                    new Bold(new Run("Filename: ")),
                    new Run(relativePath)
                });

                if (found && ctrlClickEnabled)
                {
                    textBlock.Inlines.AddRange(new Inline[] {
                        new LineBreak(),
                        new Run("Ctrl+Click to open the file")
                    });
                }
                break;

            default:
                if (!ctrlClickEnabled)
                {
                    return(null);
                }

                textBlock.Inlines.Add(new Run("Ctrl+Click to open the containing file"));
                break;
            }

            // Set the styles in order to support other themes
            textBlock.SetResourceReference(TextBlock.BackgroundProperty, EnvironmentColors.ToolTipBrushKey);
            textBlock.SetResourceReference(TextBlock.ForegroundProperty, EnvironmentColors.ToolTipTextBrushKey);

            return(textBlock);
        }
        /// <summary>
        /// This is used to get the content to add to the quick info by looking up the given topic ID to get its
        /// title and filename if possible.
        /// </summary>
        /// <param name="elementName">The element name for which to create content</param>
        /// <param name="id">The ID to look up if necessary</param>
        /// <returns>The content to add to the quick info (a text block element containing the additional info
        /// about the element)</returns>
        private UIElement CreateInfoText(string elementName, string id)
        {
            if (String.IsNullOrWhiteSpace(elementName) || String.IsNullOrWhiteSpace(id))
            {
                return(null);
            }

            var textBlock = new TextBlock();

            switch (elementName)
            {
            case "image":
            case "link":
            case "topic":
                var    projectFileSearcher = new ProjectFileSearcher(serviceProvider, null);
                string title, filename, relativePath;

                bool found = projectFileSearcher.GetInfoFor(elementName == "image" ?
                                                            ProjectFileSearcher.IdType.Image : ProjectFileSearcher.IdType.Link, id,
                                                            out title, out filename, out relativePath);

                textBlock.Inlines.AddRange(new Inline[] {
                    new Bold(new Run(elementName == "image" ? "Alternate Text: " : "Title: ")),
                    new Run(title),
                    new LineBreak(),
                    new Bold(new Run("Filename: ")),
                    new Run(relativePath)
                });

                break;

            case "codeEntityReference":
                break;

            default:
                break;
            }

            // Set the styles in order to support other themes in VS 2012 and later
            object themeKey = Utility.GetThemeKey("ToolTipBrushKey", SystemColors.ControlLightBrushKey);

            if (themeKey != null)
            {
                textBlock.SetResourceReference(TextBlock.BackgroundProperty, themeKey);
                textBlock.SetResourceReference(TextBlock.ForegroundProperty,
                                               Utility.GetThemeKey("ToolTipTextBrushKey", SystemColors.ControlTextBrushKey));
            }

            return(textBlock);
        }
        /// <inheritdoc />
        protected override void GoToDefinition(string id, string definitionType)
        {
            switch(definitionType)
            {
                case "codeEntityReference":
                    if(!IntelliSense.RoslynHacks.RoslynUtilities.IsFinalRoslyn || (id.Length > 2 && id[1] == ':'))
                    {
                        var entitySearcher = new CodeEntitySearcher(this.ServiceProvider);

                        if(!entitySearcher.GotoDefinitionFor(id))
                        {
                            Guid clsid = Guid.Empty;
                            int result;
                            var uiShell = this.ServiceProvider.GetService(typeof(SVsUIShell)) as IVsUIShell;

                            if(uiShell != null)
                                uiShell.ShowMessageBox(0, ref clsid, "Unable to navigate to XML comments member " +
                                    "definition.", String.Format(CultureInfo.CurrentCulture, "Member ID: {0}\r\n\r\n" +
                                    "If valid, the most likely cause is that it is not a member of a C# project " +
                                    "within the current solution.  Navigating to members in non-C# projects and " +
                                    ".NET Framework or reference assemblies is not supported.", id), String.Empty, 0,
                                    OLEMSGBUTTON.OLEMSGBUTTON_OK, OLEMSGDEFBUTTON.OLEMSGDEFBUTTON_FIRST,
                                    OLEMSGICON.OLEMSGICON_INFO, 0, out result);

                            System.Diagnostics.Debug.WriteLine("Unable to go to declaration for member ID: " + id);
                        }
                    }
                    else
                    {
                        // VS2015 and later do support actual Go To Definition on cref targets in XML comments
                        Guid cmdGroup = VSConstants.GUID_VSStandardCommandSet97;
                        var shellCommandDispatcher = this.ServiceProvider.GetService(
                            typeof(SUIHostCommandDispatcher)) as IOleCommandTarget;

                        shellCommandDispatcher.Exec(ref cmdGroup, (uint)VSConstants.VSStd97CmdID.GotoDefn,
                            (uint)OLECMDEXECOPT.OLECMDEXECOPT_DODEFAULT, System.IntPtr.Zero, System.IntPtr.Zero);
                    }
                    break;

                case "link":
                case "token":
                    var projectFileSearcher = new ProjectFileSearcher(this.ServiceProvider, this.TextView);

                    ProjectFileSearcher.IdType idType;

                    if(!Enum.TryParse(definitionType, true, out idType))
                        idType = ProjectFileSearcher.IdType.Unknown;

                    if(!projectFileSearcher.OpenFileFor(idType, id))
                    {
                        if(idType == ProjectFileSearcher.IdType.Link)
                            definitionType = "conceptualLink";

                        Guid clsid = Guid.Empty;
                        int result;
                        var uiShell = this.ServiceProvider.GetService(typeof(SVsUIShell)) as IVsUIShell;

                        if(uiShell != null)
                            uiShell.ShowMessageBox(0, ref clsid, "Unable to open file for XML comments element " +
                                "target.", String.Format(CultureInfo.CurrentCulture, "Type: {0}\r\nID: {1}\r\n\r\n" +
                                "If valid, it may not be a part of a help file builder project within this " +
                                "solution.", definitionType, id), String.Empty, 0, OLEMSGBUTTON.OLEMSGBUTTON_OK,
                                OLEMSGDEFBUTTON.OLEMSGDEFBUTTON_FIRST, OLEMSGICON.OLEMSGICON_INFO, 0, out result);

                        System.Diagnostics.Debug.WriteLine("Unable to go to open file for ID '{0}' ({1}): ", id,
                            definitionType);
                    }
                    break;

                default:
                    break;
            }
        }
        /// <summary>
        /// This is used to get the content to add to the quick info by looking up the given topic ID to get its
        /// title and filename if possible.
        /// </summary>
        /// <param name="elementName">The element name for which to create content</param>
        /// <param name="id">The ID to look up if necessary</param>
        /// <returns>The content to add to the quick info (a text block element containing the additional info
        /// about the element)</returns>
        private UIElement CreateInfoText(string elementName, string id)
        {
            if(String.IsNullOrWhiteSpace(elementName) || String.IsNullOrWhiteSpace(id))
                return null;

            var textBlock = new TextBlock();

            switch(elementName)
            {
                case "conceptualLink":
                    var projectFileSearcher = new ProjectFileSearcher(serviceProvider, null);
                    string title, filename, relativePath;

                    bool found = projectFileSearcher.GetInfoFor(ProjectFileSearcher.IdType.Link, id,
                        out title, out filename, out relativePath);

                    textBlock.Inlines.AddRange(new Inline[] {
                        new Bold(new Run("Title: ")),
                        new Run(title),
                        new LineBreak(),
                        new Bold(new Run("Filename: ")),
                        new Run(relativePath)
                    });

                    if(found && ctrlClickEnabled)
                        textBlock.Inlines.AddRange(new Inline[] {
                            new LineBreak(),
                            new Run("Ctrl+Click to open the file")
                        });
                    break;

                case "cref":
                    if(!ctrlClickEnabled)
                        return null;

                    if(!IntelliSense.RoslynHacks.RoslynUtilities.IsFinalRoslyn)
                        textBlock.Inlines.Add(new Run("Ctrl+Click to go to definition (within solution only)"));
                    else
                        textBlock.Inlines.Add(new Run("Ctrl+Click to go to definition"));
                    break;

                default:
                    if(!ctrlClickEnabled)
                        return null;

                    textBlock.Inlines.Add(new Run("Ctrl+Click to open the containing file"));
                    break;
            }

            // Set the styles in order to support other themes
            textBlock.SetResourceReference(TextBlock.BackgroundProperty, EnvironmentColors.ToolTipBrushKey);
            textBlock.SetResourceReference(TextBlock.ForegroundProperty, EnvironmentColors.ToolTipTextBrushKey);

            return textBlock;
        }
Example #6
0
        /// <summary>
        /// This is used to go to the definition based on the span under the cursor
        /// </summary>
        /// <param name="id">The ID of the definition to go to</param>
        /// <param name="definitionType">A definition type to further classify the ID</param>
        private void GoToDefinition(string id, string definitionType)
        {
            switch (definitionType)
            {
            case "codeEntityReference":
                if (!IntelliSense.RoslynHacks.RoslynUtilities.IsFinalRoslyn || !isCodeFile ||
                    (id.Length > 2 && id[1] == ':'))
                {
                    var entitySearcher = new CodeEntitySearcher(provider.ServiceProvider);

                    if (!entitySearcher.GotoDefinitionFor(id))
                    {
                        Guid clsid = Guid.Empty;
                        int  result;
                        var  uiShell = provider.ServiceProvider.GetService(typeof(SVsUIShell)) as IVsUIShell;

                        if (uiShell != null)
                        {
                            uiShell.ShowMessageBox(0, ref clsid, "Unable to navigate to XML comments member " +
                                                   "definition.", String.Format(CultureInfo.CurrentCulture, "Member ID: {0}\r\n\r\n" +
                                                                                "If valid, the most likely cause is that it is not a member of a C# project " +
                                                                                "within the current solution.  Navigating to members in non-C# projects and " +
                                                                                ".NET Framework or reference assemblies is not supported.", id), String.Empty, 0,
                                                   OLEMSGBUTTON.OLEMSGBUTTON_OK, OLEMSGDEFBUTTON.OLEMSGDEFBUTTON_FIRST,
                                                   OLEMSGICON.OLEMSGICON_INFO, 0, out result);
                        }

                        System.Diagnostics.Debug.WriteLine("Unable to go to declaration for member ID: " + id);
                    }
                }
                else
                {
                    // VS2015 and later do support actual Go To Definition on cref targets in XML comments
                    Guid cmdGroup = VSConstants.GUID_VSStandardCommandSet97;
                    var  shellCommandDispatcher = provider.ServiceProvider.GetService(
                        typeof(SUIHostCommandDispatcher)) as IOleCommandTarget;

                    shellCommandDispatcher.Exec(ref cmdGroup, (uint)VSConstants.VSStd97CmdID.GotoDefn,
                                                (uint)OLECMDEXECOPT.OLECMDEXECOPT_DODEFAULT, System.IntPtr.Zero, System.IntPtr.Zero);
                }
                break;

            case "codeReference":
            case "conceptualLink":
            case "image":
            case "link":
            case "token":
                var projectFileSearcher = new ProjectFileSearcher(provider.ServiceProvider, textView);

                ProjectFileSearcher.IdType idType;

                if (definitionType == "conceptualLink")
                {
                    idType = ProjectFileSearcher.IdType.Link;
                }
                else
                if (!Enum.TryParse(definitionType, true, out idType))
                {
                    idType = ProjectFileSearcher.IdType.Unknown;
                }

                if (!projectFileSearcher.OpenFileFor(idType, id))
                {
                    Guid clsid = Guid.Empty;
                    int  result;
                    var  uiShell = provider.ServiceProvider.GetService(typeof(SVsUIShell)) as IVsUIShell;

                    if (uiShell != null)
                    {
                        uiShell.ShowMessageBox(0, ref clsid, "Unable to open file for element target.",
                                               String.Format(CultureInfo.CurrentCulture, "Type: {0}\r\nID: {1}\r\n\r\nIf " +
                                                             "valid, it may not be a part of a help file builder project within this " +
                                                             "solution.", definitionType, id), String.Empty, 0, OLEMSGBUTTON.OLEMSGBUTTON_OK,
                                               OLEMSGDEFBUTTON.OLEMSGDEFBUTTON_FIRST, OLEMSGICON.OLEMSGICON_INFO, 0, out result);
                    }

                    System.Diagnostics.Debug.WriteLine("Unable to go to open file for ID '{0}' ({1}): ", id,
                                                       definitionType);
                }
                break;

            default:
                break;
            }
        }
Example #7
0
        private void GoToDefinition(string id, string definitionType)
        {
            switch (definitionType)
            {
            case "codeEntityReference":
                var entitySearcher = new CodeEntitySearcher(_provider.ServiceProvider);

                if (!entitySearcher.GotoDefinitionFor(id))
                {
                    Guid clsid = Guid.Empty;
                    int  result;
                    var  uiShell = _provider.ServiceProvider.GetService(typeof(SVsUIShell)) as IVsUIShell;

                    if (uiShell != null)
                    {
                        uiShell.ShowMessageBox(0, ref clsid, "Unable to navigate to code entity reference " +
                                               "definition.", String.Format(CultureInfo.CurrentCulture, "Member ID: {0}\r\n\r\n" +
                                                                            "If valid, the most likely cause is that it is not a member of a C# project " +
                                                                            "within the current solution.  Navigating to members in non-C# projects and " +
                                                                            ".NET Framework or reference assemblies is not supported.", id), String.Empty, 0,
                                               OLEMSGBUTTON.OLEMSGBUTTON_OK, OLEMSGDEFBUTTON.OLEMSGDEFBUTTON_FIRST,
                                               OLEMSGICON.OLEMSGICON_INFO, 0, out result);
                    }

                    System.Diagnostics.Debug.WriteLine("Unable to go to declaration for member ID: " + id);
                }
                break;

            case "codeReference":
            case "image":
            case "link":
            case "token":
                var projectFileSearcher = new ProjectFileSearcher(_provider.ServiceProvider, _textView);

                ProjectFileSearcher.IdType idType;

                if (!Enum.TryParse(definitionType, true, out idType))
                {
                    idType = ProjectFileSearcher.IdType.Unknown;
                }

                if (!projectFileSearcher.OpenFileFor(idType, id))
                {
                    if (idType == ProjectFileSearcher.IdType.Link)
                    {
                        definitionType = "conceptualLink";
                    }

                    Guid clsid = Guid.Empty;
                    int  result;
                    var  uiShell = _provider.ServiceProvider.GetService(typeof(SVsUIShell)) as IVsUIShell;

                    if (uiShell != null)
                    {
                        uiShell.ShowMessageBox(0, ref clsid, "Unable to open file for element target.",
                                               String.Format(CultureInfo.CurrentCulture, "Type: {0}\r\nID: {1}\r\n\r\nIf " +
                                                             "valid, it may not be a part of a help file builder project within this " +
                                                             "solution.", definitionType, id), String.Empty, 0, OLEMSGBUTTON.OLEMSGBUTTON_OK,
                                               OLEMSGDEFBUTTON.OLEMSGDEFBUTTON_FIRST, OLEMSGICON.OLEMSGICON_INFO, 0, out result);
                    }

                    System.Diagnostics.Debug.WriteLine("Unable to go to open file for ID '{0}' ({1}): ", id,
                                                       definitionType);
                }
                break;

            default:
                break;
            }
        }
        /// <summary>
        /// This is used to get the content to add to the quick info by looking up the given topic ID to get its
        /// title and filename if possible.
        /// </summary>
        /// <param name="elementName">The element name for which to create content</param>
        /// <param name="id">The ID to look up if necessary</param>
        /// <returns>The content to add to the quick info (a text block element containing the additional info
        /// about the element)</returns>
        private UIElement CreateInfoText(string elementName, string id)
        {
            if(String.IsNullOrWhiteSpace(elementName) || String.IsNullOrWhiteSpace(id))
                return null;

            var textBlock = new TextBlock();

            switch(elementName)
            {
                case "conceptualLink":
                    var projectFileSearcher = new ProjectFileSearcher(serviceProvider, null);
                    string title, filename, relativePath;

                    bool found = projectFileSearcher.GetInfoFor(ProjectFileSearcher.IdType.Link, id,
                        out title, out filename, out relativePath);

                    textBlock.Inlines.AddRange(new Inline[] {
                        new Bold(new Run("Title: ")),
                        new Run(title),
                        new LineBreak(),
                        new Bold(new Run("Filename: ")),
                        new Run(relativePath)
                    });

                    break;

                case "cref":
                    break;

                default:
                    break;
            }

            // Set the styles in order to support other themes in VS 2012 and later
            object themeKey = Utility.GetThemeKey("ToolTipBrushKey", SystemColors.ControlLightBrushKey);

            if(themeKey != null)
            {
                textBlock.SetResourceReference(TextBlock.BackgroundProperty, themeKey);
                textBlock.SetResourceReference(TextBlock.ForegroundProperty,
                    Utility.GetThemeKey("ToolTipTextBrushKey", SystemColors.ControlTextBrushKey));
            }

            return textBlock;
        }
        /// <inheritdoc />
        protected override void GoToDefinition(string id, string definitionType)
        {
            switch(definitionType)
            {
                case "codeEntityReference":
                    var entitySearcher = new CodeEntitySearcher(this.ServiceProvider);

                    if(!entitySearcher.GotoDefinitionFor(id))
                    {
                        Guid clsid = Guid.Empty;
                        int result;
                        var uiShell = this.ServiceProvider.GetService(typeof(SVsUIShell)) as IVsUIShell;

                        if(uiShell != null)
                            uiShell.ShowMessageBox(0, ref clsid, "Unable to navigate to code entity reference " +
                                "definition.", String.Format(CultureInfo.CurrentCulture, "Member ID: {0}\r\n\r\n" +
                                "If valid, the most likely cause is that it is not a member of a C# project " +
                                "within the current solution.  Navigating to members in non-C# projects and " +
                                ".NET Framework or reference assemblies is not supported.", id), String.Empty, 0,
                                OLEMSGBUTTON.OLEMSGBUTTON_OK, OLEMSGDEFBUTTON.OLEMSGDEFBUTTON_FIRST,
                                OLEMSGICON.OLEMSGICON_INFO, 0, out result);

                        System.Diagnostics.Debug.WriteLine("Unable to go to declaration for member ID: " + id);
                    }
                    break;

                case "codeReference":
                case "image":
                case "link":
                case "token":
                    var projectFileSearcher = new ProjectFileSearcher(this.ServiceProvider, this.TextView);

                    ProjectFileSearcher.IdType idType;

                    if(!Enum.TryParse(definitionType, true, out idType))
                        idType = ProjectFileSearcher.IdType.Unknown;

                    if(!projectFileSearcher.OpenFileFor(idType, id))
                    {
                        Guid clsid = Guid.Empty;
                        int result;
                        var uiShell = this.ServiceProvider.GetService(typeof(SVsUIShell)) as IVsUIShell;

                        if(uiShell != null)
                            uiShell.ShowMessageBox(0, ref clsid, "Unable to open file for element target.",
                                String.Format(CultureInfo.CurrentCulture, "Type: {0}\r\nID: {1}\r\n\r\nIf " +
                                "valid, it may not be a part of a help file builder project within this " +
                                "solution.", definitionType, id), String.Empty, 0, OLEMSGBUTTON.OLEMSGBUTTON_OK,
                                OLEMSGDEFBUTTON.OLEMSGDEFBUTTON_FIRST, OLEMSGICON.OLEMSGICON_INFO, 0, out result);

                        System.Diagnostics.Debug.WriteLine("Unable to go to open file for ID '{0}' ({1}): ", id,
                            definitionType);
                    }
                    break;

                default:
                    break;
            }
        }
        /// <summary>
        /// This is used to get the content to add to the quick info by looking up the given topic ID to get its
        /// title and filename if possible.
        /// </summary>
        /// <param name="elementName">The element name for which to create content</param>
        /// <param name="id">The ID to look up if necessary</param>
        /// <returns>The content to add to the quick info (a text block element containing the additional info
        /// about the element)</returns>
        private UIElement CreateInfoText(string elementName, string id)
        {
            if(String.IsNullOrWhiteSpace(elementName) || String.IsNullOrWhiteSpace(id))
                return null;

            var textBlock = new TextBlock();

            switch(elementName)
            {
                case "image":
                case "link":
                case "topic":
                    var projectFileSearcher = new ProjectFileSearcher(serviceProvider, null);
                    string title, filename, relativePath;

                    bool found = projectFileSearcher.GetInfoFor(elementName == "image" ?
                        ProjectFileSearcher.IdType.Image : ProjectFileSearcher.IdType.Link, id,
                        out title, out filename, out relativePath);

                    textBlock.Inlines.AddRange(new Inline[] {
                        new Bold(new Run(elementName == "image" ? "Alternate Text: " : "Title: ")),
                        new Run(title),
                        new LineBreak(),
                        new Bold(new Run("Filename: ")),
                        new Run(relativePath)
                    });

                    if(elementName != "topic" && found & ctrlClickEnabled)
                        textBlock.Inlines.AddRange(new Inline[] {
                            new LineBreak(),
                            new Run("Ctrl+Click to open the file")
                        });
                    break;

                case "codeEntityReference":
                    if(!ctrlClickEnabled)
                        return null;

                    textBlock.Inlines.Add(new Run("Ctrl+Click to go to definition (within solution only)"));
                    break;

                default:
                    if(!ctrlClickEnabled)
                        return null;

                    textBlock.Inlines.Add(new Run("Ctrl+Click to open the containing file"));
                    break;
            }

            // Set the styles in order to support other themes
            textBlock.SetResourceReference(TextBlock.BackgroundProperty, EnvironmentColors.ToolTipBrushKey);
            textBlock.SetResourceReference(TextBlock.ForegroundProperty, EnvironmentColors.ToolTipTextBrushKey);

            return textBlock;
        }
        /// <summary>
        /// This is used to get the content to add to the quick info by looking up the given topic ID to get its
        /// title and filename if possible.
        /// </summary>
        /// <param name="elementName">The element name for which to create content</param>
        /// <param name="id">The ID to look up if necessary</param>
        /// <returns>The content to add to the quick info (a text block element containing the additional info
        /// about the element)</returns>
        private UIElement CreateInfoText(string elementName, string id)
        {
            if (String.IsNullOrWhiteSpace(elementName) || String.IsNullOrWhiteSpace(id))
            {
                return(null);
            }

            var textBlock = new TextBlock();

            switch (elementName)
            {
            case "image":
            case "link":
            case "topic":
                var    projectFileSearcher = new ProjectFileSearcher(serviceProvider, null);
                string title, filename, relativePath;

                bool found = projectFileSearcher.GetInfoFor(elementName == "image" ?
                                                            ProjectFileSearcher.IdType.Image : ProjectFileSearcher.IdType.Link, id,
                                                            out title, out filename, out relativePath);

                textBlock.Inlines.AddRange(new Inline[] {
                    new Bold(new Run(elementName == "image" ? "Alternate Text: " : "Title: ")),
                    new Run(title),
                    new LineBreak(),
                    new Bold(new Run("Filename: ")),
                    new Run(relativePath)
                });

                if (elementName != "topic" && found & ctrlClickEnabled)
                {
                    textBlock.Inlines.AddRange(new Inline[] {
                        new LineBreak(),
                        new Run("Ctrl+Click to open the file")
                    });
                }
                break;

            case "codeEntityReference":
                if (!ctrlClickEnabled)
                {
                    return(null);
                }

                textBlock.Inlines.Add(new Run("Ctrl+Click to go to definition (within solution only)"));
                break;

            default:
                if (!ctrlClickEnabled)
                {
                    return(null);
                }

                textBlock.Inlines.Add(new Run("Ctrl+Click to open the containing file"));
                break;
            }

            // Set the styles in order to support other themes
            textBlock.SetResourceReference(TextBlock.BackgroundProperty, EnvironmentColors.ToolTipBrushKey);
            textBlock.SetResourceReference(TextBlock.ForegroundProperty, EnvironmentColors.ToolTipTextBrushKey);

            return(textBlock);
        }