| name | registering-fonts-colors |
| description | Register custom font and color categories on the Tools > Options > Fonts and Colors page. Use when the user asks about user-customizable syntax colors, creating a Fonts and Colors category, BaseFontAndColorCategory, IVsFontAndColorDefaults, ColorDefinition, or reading configured font/color settings at runtime in a Visual Studio IDE extension. Covers VisualStudio.Extensibility (out-of-process), VSIX Community Toolkit (in-process), and legacy VSSDK (in-process) approaches. |
Fonts & Colors in Visual Studio Extensions
Extensions can register custom font and color categories that appear on the Tools > Options > Environment > Fonts and Colors page. Users can then customize foreground, background, and font styles for each item your extension defines.
This is different from general theming (matching VS's Light/Dark theme). This is about letting users customize your extension's display items — like a custom editor's syntax colors.
Registering custom Fonts & Colors items gives users control over your extension's visual appearance through the standard VS settings page they already know. Without it, your extension either hard-codes colors (which break in different themes) or requires its own custom settings UI. Fonts & Colors entries also integrate with the VS theme system — they can have default values per theme (Light, Dark, High Contrast) that VS applies automatically when the user switches themes.
When to use this vs. alternatives:
- User-customizable colors for extension-specific display items → Fonts & Colors (this skill)
- Matching your WPF UI to the current VS theme (Light/Dark/HC) → vs-theming
- Syntax coloring via classification types → vs-editor-classifier (classifications auto-appear in Fonts & Colors)
- Extension settings beyond colors (booleans, strings, enums) → vs-options-settings
1. VSIX Community Toolkit (in-process)
The toolkit wraps the complex VSSDK registration with three building blocks:
BaseFontAndColorCategory<T> — defines a category with its default font and color items.
BaseFontAndColorProvider — discovers categories and serves them to Visual Studio.
VS.FontsAndColors — reads the user's configured colors at runtime.
NuGet package: Community.VisualStudio.Toolkit
Key namespace: Community.VisualStudio.Toolkit
Step 1 — Define a category
Create a class inheriting from BaseFontAndColorCategory<T>. Give it a unique [Guid], a display Name, and one or more ColorDefinition properties.
using System.Runtime.InteropServices;
using Community.VisualStudio.Toolkit;
using Microsoft.VisualStudio.Shell.Interop;
[Guid("e977c587-c06e-4c1d-8a3a-cbf9da1bdafa")]
public class MyColorCategory : BaseFontAndColorCategory<MyColorCategory>
{
public MyColorCategory() : base(new FontDefinition("Consolas", 10)) { }
public override string Name => "My Extension Colors";
public ColorDefinition Keyword { get; } = new(
"Keyword",
defaultForeground: VisualStudioColor.Indexed(COLORINDEX.CI_BLUE),
defaultBackground: VisualStudioColor.Automatic()
);
public ColorDefinition Comment { get; } = new(
"Comment",
defaultForeground: VisualStudioColor.Indexed(COLORINDEX.CI_DARKGREEN),
defaultBackground: VisualStudioColor.Automatic(),
fontStyle: FontStyle.Italic
);
public ColorDefinition Error { get; } = new(
"Error",
defaultForeground: VisualStudioColor.Indexed(COLORINDEX.CI_RED),
defaultBackground: VisualStudioColor.Automatic(),
fontStyle: FontStyle.Bold
);
}
Each ColorDefinition property is automatically discovered. The name parameter passed to the constructor is what appears on the options page.
Color values
| Factory method | Description |
|---|
VisualStudioColor.Indexed(COLORINDEX.CI_*) | Standard VS color index |
VisualStudioColor.VsColor(__VSSYSCOLOREX.VSCOLOR_*) | VS themed system color |
VisualStudioColor.Automatic() | Let VS choose based on the current theme |
Color options
Control what the user can customize:
public ColorDefinition Literal { get; } = new(
"Literal",
defaultForeground: VisualStudioColor.Indexed(COLORINDEX.CI_MAROON),
options: ColorOptions.AllowForegroundChange | ColorOptions.AllowBoldChange
);
Step 2 — Define a provider
Create a class inheriting from BaseFontAndColorProvider. It needs its own [Guid]. The provider automatically discovers all BaseFontAndColorCategory<T> classes in the same assembly.
[Guid("26442428-2cd7-4d79-8498-f9b14087ca50")]
public class MyFontAndColorProvider : BaseFontAndColorProvider { }
Step 3 — Register in the package
Add the [ProvideFontsAndColors] attribute to your package class and call RegisterFontAndColorProvidersAsync() during initialization.
[PackageRegistration(UseManagedResourcesOnly = true, AllowsBackgroundLoading = true)]
[Guid(PackageGuids.MyPackageString)]
[ProvideFontsAndColors(typeof(MyFontAndColorProvider))]
public sealed class MyPackage : ToolkitPackage
{
protected override async Task InitializeAsync(
CancellationToken cancellationToken,
IProgress<ServiceProgressData> progress)
{
await this.RegisterFontAndColorProvidersAsync();
}
}
Reading configured colors at runtime
ConfiguredFontAndColorSet config =
await VS.FontsAndColors.GetConfiguredFontAndColorsAsync<MyColorCategory>();
ConfiguredFont font = config.Font;
string fontFamily = font.FamilyName;
ushort fontSize = font.Size;
MyColorCategory category = MyColorCategory.Instance;
ConfiguredColor keywordColor = config.GetColor(category.Keyword);
System.Drawing.Color foreground = keywordColor.ForegroundColor;
System.Drawing.Color background = keywordColor.BackgroundColor;
The returned ConfiguredFontAndColorSet is live — it raises change notifications when the user modifies colors while your extension is running.
Listening for changes
ConfiguredColor latest = config.GetColor(category.Keyword);
2. VSSDK (in-process, legacy)
The VSSDK requires implementing IVsFontAndColorDefaults and registering via the registry.
NuGet package: Microsoft.VisualStudio.SDK
Key namespaces: Microsoft.VisualStudio.Shell.Interop, Microsoft.VisualStudio.Shell
Implement IVsFontAndColorDefaults
Your VSPackage must implement IVsFontAndColorDefaultsProvider and return an IVsFontAndColorDefaults instance for each category GUID.
Each IVsFontAndColorDefaults implementation must provide:
- Lists of display items in the category
- Localizable names for display items
- Display information for each member (foreground, background, font flags)
Register the category
In your .pkgdef or via registry attributes:
[$RootKey$\FontAndColors\My Extension Colors]
"Category"="{e977c587-c06e-4c1d-8a3a-cbf9da1bdafa}"
"Package"="{your-package-guid}"
Read stored settings via IVsFontAndColorStorage
IVsFontAndColorStorage storage = (IVsFontAndColorStorage)
GetService(typeof(SVsFontAndColorStorage));
Guid categoryGuid = new Guid("e977c587-c06e-4c1d-8a3a-cbf9da1bdafa");
storage.OpenCategory(ref categoryGuid, (uint)__FCSTORAGEFLAGS.FCSF_READONLY);
ColorableItemInfo[] itemInfo = new ColorableItemInfo[1];
storage.GetItem("Keyword", itemInfo);
uint foreground = itemInfo[0].crForeground;
storage.CloseCategory();
Respond to changes
Implement IVsFontAndColorEvents or poll via IVsFontAndColorStorage. Use IVsFontAndColorCacheManager to flush stale caches before reading.
Note: The raw VSSDK approach is significantly more boilerplate than the toolkit. Use the Community Toolkit's BaseFontAndColorCategory<T> when possible.
3. VisualStudio.Extensibility (out-of-process)
The VisualStudio.Extensibility SDK does not currently provide an API for registering custom Fonts and Colors categories. This feature requires in-process registration via COM interfaces.
If you need Fonts and Colors support from an out-of-process extension, use a mixed in-proc/out-of-proc extension pattern with an in-process companion that handles the registration.
Troubleshooting
- Items don't appear in Fonts & Colors page: Verify the
[ProvideEditorFormatDefinition] or [ProvideFontAndColorsCategory] attributes are present on your package. For classifications, ensure [UserVisible(true)] is set on the ClassificationFormatDefinition.
- Colors reset when switching themes: You need to define per-theme defaults. Use the VS theme-aware color APIs or
ThemeResourceKey to specify different defaults for Light, Dark, and High Contrast.
- Custom colors don't update when user changes them in settings: You're caching the color at startup. Subscribe to
IVsFontAndColorEvents to get notified when settings change.
- Colors look wrong in High Contrast mode: You're hard-coding RGB values. Use system colors or VS theme tokens for High Contrast.
What NOT to do
Do NOT hard-code RGB color values without per-theme defaults — colors that look good in Light can be invisible in Dark or High Contrast.
Do NOT create your own color-picker settings UI — use the VS Fonts & Colors infrastructure.
Do NOT use System.Drawing.Color or System.Windows.Media.Color directly in WPF — use ThemeResourceKey or VS color service bindings.
See also
Additional resources