I want to host two different VS C#/VB editors (as wpf controls) created via the IVsInvisibleEditorManager.RegisterInvisibleEditor method in my custom pane inherited from IVsUIElementPane and IVsPersistDocData interfaces. But highlighting works only for one
editor.
I use the following code for creating editor
private void SetLeftDisplayedFile(string filePath)
{
ThreadHelper.ThrowIfNotOnUIThread();
ErrorHandler.ThrowOnFailure(_invisibleEditorManager.RegisterInvisibleEditor(filePath,
pProject: null,
dwFlags: (uint)_EDITORREGFLAGS.RIEF_ENABLECACHING,
pFactory: null,
ppEditor: out invisibleEditorLeft));
RegisterDocument(filePath);
IntPtr docDataPointer = IntPtr.Zero;
Guid guidIVSTextLines = typeof(IVsTextLines).GUID;
ErrorHandler.ThrowOnFailure(invisibleEditorLeft.GetDocData(fEnsureWritable: 1, riid: ref guidIVSTextLines, ppDocData: out docDataPointer));
try
{
IVsTextLines docData = (IVsTextLines)Marshal.GetObjectForIUnknown(docDataPointer);
//Create a code window adapter.
codeWindowLeft = _editorAdapter.CreateVsCodeWindowAdapter(VisualStudioServices.OLEServiceProvider);
const _codewindowbehaviorflags CWB_DISABLEDIFF = (_codewindowbehaviorflags)0x04;
IVsCodeWindowEx codeWindowEx = (IVsCodeWindowEx)codeWindowLeft;
INITVIEW[] initView = new INITVIEW[1];
codeWindowEx.Initialize((uint)_codewindowbehaviorflags.CWB_DISABLESPLITTER | (uint)CWB_DISABLEDIFF,
VSUSERCONTEXTATTRIBUTEUSAGE.VSUC_Usage_Filter,
szNameAuxUserContext: "",
szValueAuxUserContext: "",
InitViewFlags: 0,
pInitView: initView);
//Associate our IVsTextLines with our new code window.
ErrorHandler.ThrowOnFailure(codeWindowLeft.SetBuffer((IVsTextLines)docData));
//Get our text view for our editor which we will use to get the WPF control that hosts said editor.
ErrorHandler.ThrowOnFailure(codeWindowLeft.GetPrimaryView(out textViewLeft));
//Get our WPF host from our text view (from our code window).
IWpfTextViewHost textViewHost = _editorAdapter.GetWpfTextViewHost(textViewLeft);
Debug.Assert(this.control != null);
//We already have an open window, so just insert this editor in place of the old one.
this.control.InsertLeftEditor(textViewHost.HostControl);
}
finally
{
if (docDataPointer != IntPtr.Zero)
{
//Release the doc data from the invisible editor since it gave us a ref-counted copy.
Marshal.Release(docDataPointer);
}
}
}
private uint RegisterDocument(string targetFile)
{
//Then when creating the IVsInvisibleEditor, find and lock the document
uint itemID;
IntPtr docData;
uint docCookie;
IVsHierarchy hierarchy;
var runningDocTable = (IVsRunningDocumentTable)Microsoft.VisualStudio.Shell.Package.GetGlobalService(typeof(SVsRunningDocumentTable));
ErrorHandler.ThrowOnFailure(runningDocTable.FindAndLockDocument(
dwRDTLockType: (uint)_VSRDTFLAGS.RDT_NoLock,
pszMkDocument: targetFile,
ppHier: out hierarchy,
pitemid: out itemID,
ppunkDocData: out docData,
pdwCookie: out docCookie));
return docCookie;
}
The custom pane (see all code in my project on
One Drive):
VsWpfCompareWindowPane : IVsUIElementPane, IVsPersistDocData
{
...
int IVsUIElementPane.CreateUIElementPane(out object punkUIElement)
{
if (control == null)
{
control = new WpfCompareControl();
if (!string.IsNullOrEmpty(_leftFilePath))
{
SetLeftDisplayedFile(_leftFilePath);
}
if (!string.IsNullOrEmpty(_rightFilePath))
{
SetRightDisplayedFile(_rightFilePath);
}
}
punkUIElement = control;
return VSConstants.S_OK;
}
...
}
In the WpfCompareControl I use two ContentControl.
STR:
- Download and build my solution on
One Drive
- In the properties of the "TestEditor" project, select Start External program and use the path to VS 2019 devenv.exe
- Set the command line arguments to “/rootsuffix Exp”
- Save and then run the solution or download and install the .vsix
- Create test.testdiff file and add paths to two .cs files on your computer. For example
C:\Users\MstislavS\Source\repos\WpfApp10\WpfApp10\MainWindow2.xaml.cs
C:\Users\MstislavS\Source\repos\WpfApp10\WpfApp10\MainWindow.xaml.cs
Save the test.testdiff file. In VS, click File-Open-File... and select the test.testdiff file.
Actual Result: Syntax highlighting and intellisence works only in the right editor, the left editor does not have syntax highlighting
![]()
but includes the same parts as the right one (bar items, scroll, zoom)
Expected result: Syntax highlighting and intellisence works in both editors.
Note: Syntax highlighting will work in both editors if you open any .cs file (File-Open-file...) after starting VS and before opening the test.testdiff file.
I have found the following
article. Calling the runningDocTable.FindAndLockDocument and SetLanguageServiceID methods does not solve the problem. This post
describes new mechanisms of creating editors in VS 2019, but doesn't solve my problem.
This problem reproduces only for Roslyn languages C# and
VB, but xml, typescript, json etc editors work fine!
Syntax highlighting also does not work in ProjectionBufferTutorial example.