2 minute read

While implementing a custom CodeSmith Generator Template Editor into Visual Studio 2010. I ran into an issue with getting the GoTo Line functionality to work properly. According to Microsoft this functionality needs to be provided by the custom editor as well as the GoTo Line dialog will need to be implemented as there is no “official public extension point”. This makes sense if you are taking over control of the editor but I feel that Microsoft should expose this dialog. I was able to implement this functionality by adding a command to the IMenuCommandService.

var mcs = GetService(typeof (IMenuCommandService)) as IMenuCommandService;
if (null != mcs)
    addCommand(mcs, VSConstants.GUID_VSStandardCommandSet97, (int) VSConstants.VSStd97CmdID.Goto, OnGoTo, OnQueryGoTo);
....
private static void addCommand(
    IMenuCommandService mcs, Guid menuGroup, int cmdID, EventHandler commandEvent, EventHandler queryEvent
) {}

Next, I see if the command should be enabled by seeing if the current document has any lines of text. Then I make a call to the “internal” Microsoft Dialog GoTo dialog that provides validation and help text. Please note that this code requires the following import block and is subject to change in future versions of Visual Studio.

using Microsoft.Internal.VisualStudio.PlatformUI;
private void OnQueryGoTo(object sender, EventArgs e)
{
    var command = (OleMenuCommand)sender;
    command.Enabled = EditorControl.LineCount > 0;
}

private void OnGoTo(object sender, EventArgs e)
{
    var lineNumber = GetGoToLineNumberFromDialog();
    if (lineNumber < 0)
        return;

    ((IVsFindTarget) this).NavigateTo(
        new TextSpan[] { new TextSpan { iStartLine = lineNumber, iStartIndex = 0,
                                        iEndLine = lineNumber, iEndIndex = 0 }});
}

private int GetGoToLineNumberFromDialog()
{
    var dataSource = new UIDataSource();
    dataSource.AddBuiltInProperty("MinimumLine", 1);
    dataSource.AddBuiltInProperty("MaximumLine", EditorControl.LineCount);
    dataSource.AddBuiltInProperty("CurrentLine", EditorControl.CurrentLine);
    WindowHelper.AddHelpTopic(dataSource, "vs.gotoline");
    if (WindowHelper.ShowModalElement(VSConstants.GUID_VSStandardCommandSet97, 231, dataSource) == 1)
    {
        var result = new UIObject(dataSource["CurrentLine"]);
        return (((int)result.Data) - 1);
    }

    return -1;
}

If anyone comes across a better way to accomplish this, by all means let me know!

Join the mailing list

Get notified of new posts and related content to your inbox. I will never sell you anything and I will NEVER sell your email address.