VS now comes with an interactive window, but unlike running the raw CSI.EXE Roslyn process, Visual Studio adds IntelliSense and a few other features such as being able to load in the current project.
I want to write a VS plug-in that tracks all text editor changes in this window. Is this possible? What I'm looking for is something akin to PreviewKeyDown/PreviewTextInput
WPF events. Can I get those on the C# interactive window and, if so, how?
Here's how far I got so far:
var dte = Shell.Instance.GetComponent<DTE>();
foreach (Window window in dte.MainWindow.Collection)
{
if (window.Kind.ToUpper().Contains("TOOL"))
{
if (window.Caption == "C# Interactive")
{
WpfWindow wpfWindow = (WpfWindow)HwndSource.FromHwnd((IntPtr) window.HWnd).RootVisual;
for (int i = 0; i < VTH.GetChildrenCount(wpfWindow); ++i)
{
// now what?
}
}
}
}
What Does Track Changes Mean? Track changes is a feature within most word processing applications that enables a user to keep track of the entire different types of alterations, changes or deletions made to a specific document.
When you want to see who's changing what in your document (or when you want someone else to see what you changed in their document), turn on Track Changes. When you want to see who's changing what in your document, click REVIEW > Track Changes to turn on Track Changes.
Turn on Track ChangesOn the Review tab, select Track Changes. In the Track Changes drop-down list, select one of the following: To track only the changes that you make to the document, select Just Mine. To track changes to the document made by all users, select For Everyone.
A comment is a note or annotation that an author or reviewer adds to a document. Word displays the comment in a balloon in the margin of the document or in the Reviewing Pane. Track changes does not need to be on for comments to be added.
Here is some code that will get an IWpfTextViewHost reference on the C# interactive Window. From there, you can have access to all text services from Visual Studio: Text lines, Text buffer, etc. (or you can hook directly on WPF's controls, which I don't recommend)
// get global UI shell service from a service provider
var shell = (IVsUIShell)ServiceProvider.GetService(typeof(SVsUIShell));
// try to find the C# interactive Window frame from it's package Id
// with different Guids, it could also work for other interactive Windows (F#, VB, etc.)
var CSharpVsInteractiveWindowPackageId = new Guid("{ca8cc5c7-0231-406a-95cd-aa5ed6ac0190}");
// you can use a flag here to force open it
var flags = __VSFINDTOOLWIN.FTW_fFindFirst;
shell.FindToolWindow((uint)flags, ref CSharpVsInteractiveWindowPackageId, out IVsWindowFrame frame);
// available?
if (frame != null)
{
// get its view (it's a WindowPane)
frame.GetProperty((int)__VSFPROPID.VSFPROPID_DocView, out object dv);
// this pane implements IVsInteractiveWindow (you need to add the Microsoft.VisualStudio.VsInteractiveWindow nuget package)
var iw = (IVsInteractiveWindow)dv;
// now get the wpf view host
// using an extension method from Microsoft.VisualStudio.VsInteractiveWindowExtensions class
IWpfTextViewHost host = iw.InteractiveWindow.GetTextViewHost();
// you can get lines with this
var lines = host.TextView.TextViewLines;
// and subscribe to events in text with this
host.TextView.TextBuffer.Changed += TextBuffer_Changed;
}
private void TextBuffer_Changed(object sender, TextContentChangedEventArgs e)
{
// text has changed
}
Note "Microsoft.VisualStudio.VsInteractiveWindow" assembly is not specifically documented but the source is open: http://sourceroslyn.io/#Microsoft.VisualStudio.VsInteractiveWindow
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With