Dynamically changing the theme

SyntaxEditor for Windows Forms Forum

The latest build of this product (v2020.1 build 0403) was released 2 months ago, which was before this thread was created.
Posted 1 month ago by Marc Beeson - Precision Mining
Version: 20.1.0402
Avatar

I am trying to use the C# vssettings dark theme provided with the sample projects by applying it to a custom HighlightingStyleRegistry. The caveat is our application uses other custom language definitions and we also allow changing the theme without restarting the app.

The problem I am facing is after setting SyntaxEditor.HighlightingStyleRegistry with the custom C# HighlightingStyleRegistry object, all highlighting is removed and I just get black text on a white background.

Here is the abbreviated code I am using to set the C# dark theme:

new DisplayItemClassificationTypeProvider().RegisterAll();
var registry = new HighlightingStyleRegistry();
// copy types and styles so the ImportHighlightingStyles works
var classificationTypes = AmbientHighlightingStyleRegistry.Instance.ClassificationTypes.ToArray();
var highlightingStyles = AmbientHighlightingStyleRegistry.Instance.HighlightingStyles.ToArray();
for (var i = 0; i < classificationTypes.Length; i++)
{
    var classificationType = classificationTypes[i];
    var highlightingStyle = highlightingStyles[i];
    var newClassificationType = new ClassificationType(classificationType.Key, classificationType.Description);
    var newHighlightStyle = new HighlightingStyle(highlightingStyle.Foreground, highlightingStyle.Background, highlightingStyle.Bold, highlightingStyle.Italic, highlightingStyle.UnderlineKind, highlightingStyle.BackgroundSpansVirtualSpace);
    registry.Register(newClassificationType, newHighlightStyle);
}
using (var stream = new MemoryStream(Properties.Resources.DarkTheme))
    registry.ImportHighlightingStyles(stream);

syntaxEditor.HighlightingStyleRegistry = registry;

This is called while the SyntaxEditor is showing. I don't really want to use the AmbientHighlightingStyleRegistry.Instance as other SyntaxEditor's will be using other dark theme HighlightingStyleRegistry's. If I set SyntaxEditor.HighlightingStyleRegistry back to null (Light theme), then the highlighting works as expected.

Is there a way to import the vssettings file into a custom HighlightingStyleRegistry?

Do I need to copy the highlighting types and styles from the AmbientHighlightingStyleRegistry instance?

Comments (4)

Posted 1 month ago by Marc Beeson - Precision Mining
Avatar

Ah nevermind, I figure out what was going one. I had left a line of code in that was assigning an empty HighlightingStyleRegistry to the SyntaxEditor.

My question still stands about copying the highlighting types and styles from the AmbientHighlightingStyleRegistry instance. Do we need to do that?

I am finding that copying the types and styles is giving inconsistent results where the forecolors are not what I would expect for my custom languages. I suspect it is because the ambient registry has styles from the C# language definition that are overlapping. If that is the case, then I will have to come up with some way to manually register types/styles.

[Modified 1 month ago]

Answer - Posted 1 month ago by Actipro Software Support - Cleveland, OH, USA
Avatar

Hi Marc,

Importing a .vssettings file will only overwrite the existing style entries in a particular IHighlightingStyleRegistry.  When the SyntaxEditor.HighlightingStyleRegistry property is null, that SyntaxEditor will use the AmbientHighlightingStyleRegistry.Instance's IHighlightingStyleRegistry. 

If you are wanting to use a secondary custom IHighlightingStyleRegistry, and want to properly import a .vssettings file into it, you would need to follow these steps:

  1. Create the HighlightingStyleRegistry instance.
  2. Ensure the HighlightingStyleRegistry has an IClassificationType registered for EVERY classification type that can possibly be used by your app, whether it comes from DisplayItemClassificationTypeProvider or ANY of your syntax languages you support.  You could manually register a simple empty Style for each of these classification types since your import will override them.  Or if you already did thise for the AmbientHighlightingStyleRegistry.Instance, you could enumerate the registrations there and copy them over.  The main thing is to make sure you have an entry for every possible classification type.
  3. Make sure you .vssettings file has an entry for EVERY classification type that is registered in the previous step.
  4. Import the .vssettings file into the registry, and it should now update the IHighlightingStyle for each IClassificationType that has been registered.
  5. Set the SyntaxEditor.HighlightingStyle property to your HighlightingStyleRegistry instance.  You can reuse the instance among multiple SyntaxEditor instances if you wish.

On a side note, the DisplayItemClassificationTypeProvider constructor lets you specify an alternate IHighightingStyleRegistry.  So you can use this code to initialize those classification types (with default light theme colors) in a registry:

new DisplayItemClassificationTypeProvider(registry).RegisterAll();

I hope that helps!


Actipro Software Support

Posted 1 month ago by Marc Beeson - Precision Mining
Avatar

Hi, that did help. Thanks for the detailed explanation. I did get it going but there seems to be a quirk in my implementation. The caret indicator remains dark when applying the dark theme when used in complex UI controls. I will send an email to ActiPro support with a simplified sample project that shows what the problem is.

I also found a easy solution to pre-populate ClassificationType's and HighlightingStyle's if you are using a custom Language that was made using the Language editor:

var registry = new HighlightingStyleRegistry();
new MyClassificationTypeProvider(registry).RegisterAll();
new DisplayItemClassificationTypeProvider(registry).RegisterAll();
using (var stream = new MemoryStream(Properties.Resources.MyDarkTheme))
    registry.ImportHighlightingStyles(stream);

[Modified 1 month ago]

Answer - Posted 1 month ago by Actipro Software Support - Cleveland, OH, USA
Avatar

Hi Marc,

Yes that code snippet will work great.

Thanks for the sample regarding the caret issue.  We found the bug and fixed it for v21.1.  In the meantime, you can work around it with this code in your SyntaxEditorEx class, which will clear the caret color cache:

protected override void OnVisibleChanged(EventArgs e) {
    base.OnVisibleChanged(e);
    this.IsOverwriteModeActive = true;
    this.IsOverwriteModeActive = false;
}

Or as you saw in your related ticket reply, you can use the new SyntaxEditor.UseInvertedCaret property instead of manually changing the caret color.


Actipro Software Support

Add Comment

Please log in to a validated account to post comments.