locked
VSIX: How do you update the colors of an Output Classifier at runtime RRS feed

  • Question

  • Given an output classifier as follows:

     

       public static class OutputClassificationDefinitions
        {
            [Export]
            [Name("bos.build.header")]
            [BaseDefinition("bos.build")]
            public static readonly ClassificationTypeDefinition BuildHeaderDefinition;
    
            [Name("bos.build.header")]
            [Export(typeof(EditorFormatDefinition))]
            [ClassificationType(ClassificationTypeNames = "bos.build.header")]
            public sealed class BuildHeaderFormat : ClassificationFormatDefinition
            {
                public BuildHeaderFormat()
                {
                    ForegroundColor = Properties.Settings.Default.BuildHeaderForerground;
                    BackgroundColor = Properties.Settings.Default.BuildHeaderBackground;
                }
            }
    
        ...
    

    As far as I can tell, VS only calls BuildHeaderFormat() once after the classifier is registered. So how does one update the colors later (i.e. user changes colors) without restarting VS?

     

     

     


    Wednesday, November 23, 2011 6:09 PM

Answers

  • Hello Mike,

    Your code looks correct, except it is fetching the wrong IClassificationFormatMap. The appearance category that you pass, should match that of the text views of your interest. As far as I know, none of them have "Text Editor".

    If you have a specific view at time of modification of your properties, you can just use the overload of GetClassificationFormatMap that takes an IWpfTextView as the input.

    If you don't have a text view at the time of the change, you'll need to calculate the correct appearance category string using the FontsAndColorsCategory class (this is found in Microsoft.VisualStudio.Editor.dll).

    Each of the categories that you see in the fonts & colors dialog that are related to the text editor (e.g. Text Editor, Output Window, Immediate Window, etc.) are composed of two GUIDs, a font category and a color cagetory. Let's suppose you want to change the colors for a C# file in the main editor windows. Then you would do:

    FontsAndColorsCategory category = new FontsAndColorsCategory(FontsAndColorsCategory.TextEditor, FontsAndColorsCategory.TextEditor, C# Language Service GUID); [You can obtain the FontsAndColorsCategory.TextEditor from Microsoft.VisualStudio.Shell.Interop.8.0.dll]

    IClassificationFormatMap map = ClassificationFormatMapService.GetClassificationFormatMap(category.AppearanceCategory);

    Now, having said all that, it just seems you want to allow the user to change the properties of your item. If that's your intention, then all you have to do is to put a UserVisible(true) as an attribute on your EditorFormatDefinition export and the item will show up in the Fonts and Colors dialog and the user will be able to modify it using the dialog (and the editor takes care of all the map updating for you). Be sure to return a valid string on the DisplayName property of EditorFormatDefinition so that the editor knows what to display in the fonts and colors dialog.

    Good luck!

    -Ameen

    Wednesday, November 23, 2011 11:58 PM

All replies

  • I believe, though I am not an editor dev nor well versed in editor extensibility points, you would grab the IClassificationFormatMap for the view and use it to retrieve the various formats you want to modify and then modify them and set them back into the map.

    Ryan

    Wednesday, November 23, 2011 8:59 PM
  • Seems like the right approach but I'm not getting it to work for some reason.

                var test = ClassificationFormatService.GetClassificationFormatMap("Text Editor");
                var type = ClassificationRegistry.GetClassificationType("bos.build.header");
                var prop = test.GetExplicitTextProperties(type);
                var blue = prop.SetForeground(Colors.Blue);
                test.SetExplicitTextProperties(type, blue);
    
    

    After setting the text properties I would expect the blue color in my output. However, it remains the original color that I set it at (Green in this case).

    Wednesday, November 23, 2011 10:00 PM
  • Hello Mike,

    Your code looks correct, except it is fetching the wrong IClassificationFormatMap. The appearance category that you pass, should match that of the text views of your interest. As far as I know, none of them have "Text Editor".

    If you have a specific view at time of modification of your properties, you can just use the overload of GetClassificationFormatMap that takes an IWpfTextView as the input.

    If you don't have a text view at the time of the change, you'll need to calculate the correct appearance category string using the FontsAndColorsCategory class (this is found in Microsoft.VisualStudio.Editor.dll).

    Each of the categories that you see in the fonts & colors dialog that are related to the text editor (e.g. Text Editor, Output Window, Immediate Window, etc.) are composed of two GUIDs, a font category and a color cagetory. Let's suppose you want to change the colors for a C# file in the main editor windows. Then you would do:

    FontsAndColorsCategory category = new FontsAndColorsCategory(FontsAndColorsCategory.TextEditor, FontsAndColorsCategory.TextEditor, C# Language Service GUID); [You can obtain the FontsAndColorsCategory.TextEditor from Microsoft.VisualStudio.Shell.Interop.8.0.dll]

    IClassificationFormatMap map = ClassificationFormatMapService.GetClassificationFormatMap(category.AppearanceCategory);

    Now, having said all that, it just seems you want to allow the user to change the properties of your item. If that's your intention, then all you have to do is to put a UserVisible(true) as an attribute on your EditorFormatDefinition export and the item will show up in the Fonts and Colors dialog and the user will be able to modify it using the dialog (and the editor takes care of all the map updating for you). Be sure to return a valid string on the DisplayName property of EditorFormatDefinition so that the editor knows what to display in the fonts and colors dialog.

    Good luck!

    -Ameen

    Wednesday, November 23, 2011 11:58 PM
  • Ameen,

    I do want to change just the properties of my item. I tried the UserVisible(true) route a while ago but it didn't work entirely. The items show up in the Font and Colors dialog just fine, but the changes are never reflected back to the EditorFormatDefinition.

    My extension is simply coloring the output of the debug window so I can highlight some debug messages I'm interested in. It works well enough with a preset color but I can't change the color via the F&C dialog. The items appear in the dialog. Heck, it even remembers the new color from instance to instance. But the new color never appears in the debug output window. Only the original preset color.

    I can upload the code if that would help. It's not very much code.

    Thursday, November 24, 2011 12:57 AM
  • Now, having said all that, it just seems you want to allow the user to change the properties of your item. If that's your intention, then all you have to do is to put a UserVisible(true) as an attribute on your EditorFormatDefinition export and the item will show up in the Fonts and Colors dialog and the user will be able to modify it using the dialog (and the editor takes care of all the map updating for you). Be sure to return a valid string on the DisplayName property of EditorFormatDefinition so that the editor knows what to display in the fonts and colors dialog.

    Good luck!

    -Ameen

    As far as I can tell, the "Output Windows" require some extra work to pickup on color changes. You can decorate an exported EditorFormatDefinition with UserVisible(true) and it will appear in the Fonts and Dialogs dialog under Text Editor. The F&C dialog even accepts and remembers changes. These changes however are not reflected back to the "Output Window". All the other extensions I've looked at work on the text editor window. 

    So what's unique about my situation is that I'm working in the Output Window. I suspect there's some appearance category hack needed. Ideally, I'd like to have my new format definitions appear in the Ouput Window section of the F&C dialog as well.

    Now that I understand the main difference b/t my extension and many of the samples here, I'm going to close this question and ask a new one specific to the Output Window. Many thanks for everyone's help.

    Saturday, November 26, 2011 12:36 PM
  • Hi Mike,

    Thank you for your update.

    To close this thread, you can mark some helpful reply as answer.

    Regards,

    Yi


    Yi Feng Li [MSFT]
    MSDN Community Support | Feedback to us
    Monday, November 28, 2011 2:07 AM