在 C# 交互中跟踪更改 window
Tracking changes in C# interactive window
VS 现在带有交互式 window,但与 运行 原始 CSI.EXE Roslyn 进程不同,Visual Studio 添加了 IntelliSense 和一些其他功能,例如能够在当前项目中加载。
我想编写一个 VS 插件来跟踪此 window 中所有文本编辑器的更改。这可能吗?我正在寻找类似于 PreviewKeyDown/PreviewTextInput
WPF 事件的东西。我可以在 C# 交互式 window 上获得这些吗?如果可以,如何获得?
这是我到目前为止的进展:
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?
}
}
}
}
这是一些代码,将在 C# 交互式 Window 上获得 IWpfTextViewHost 引用。从那里,您可以访问来自 Visual Studio 的所有文本服务:文本行、文本缓冲区等(或者您可以直接挂钩 WPF 的控件,我不推荐这样做)
// 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
}
注意 "Microsoft.VisualStudio.VsInteractiveWindow" 程序集没有具体记录,但源是开放的:http://sourceroslyn.io/#Microsoft.VisualStudio.VsInteractiveWindow
VS 现在带有交互式 window,但与 运行 原始 CSI.EXE Roslyn 进程不同,Visual Studio 添加了 IntelliSense 和一些其他功能,例如能够在当前项目中加载。
我想编写一个 VS 插件来跟踪此 window 中所有文本编辑器的更改。这可能吗?我正在寻找类似于 PreviewKeyDown/PreviewTextInput
WPF 事件的东西。我可以在 C# 交互式 window 上获得这些吗?如果可以,如何获得?
这是我到目前为止的进展:
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?
}
}
}
}
这是一些代码,将在 C# 交互式 Window 上获得 IWpfTextViewHost 引用。从那里,您可以访问来自 Visual Studio 的所有文本服务:文本行、文本缓冲区等(或者您可以直接挂钩 WPF 的控件,我不推荐这样做)
// 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
}
注意 "Microsoft.VisualStudio.VsInteractiveWindow" 程序集没有具体记录,但源是开放的:http://sourceroslyn.io/#Microsoft.VisualStudio.VsInteractiveWindow