2017-12-14 169 views
9

VS ma teraz interaktywne okno, ale w przeciwieństwie do uruchamiania surowego procesu CSI.EXE Roslyn, Visual Studio dodaje IntelliSense i kilka innych funkcji, takich jak możliwość załadowania do bieżącego projektu.Śledzenie zmian w interaktywnym oknie C#

Chcę napisać wtyczkę VS, która śledzi wszystkie zmiany edytora tekstu w tym oknie. czy to możliwe? Czego szukam to coś podobnego do zdarzeń WPF PreviewKeyDown/PreviewTextInput. Czy mogę uzyskać te w interaktywnym oknie C#, a jeśli tak, w jaki sposób?

Oto jak daleko mam do tej pory:

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? 
     } 
    } 
    } 
} 
+0

Meh, inny przypadek * jego nieudokumentowanego *, dosłownie nie ma dokumentacji dotyczącej używania 'EnvDTE Interactive': https://docs.microsoft. com/en-us/dotnet/api/envdte.outputwindow.dte? view = visualstudiosdk-2017 –

+0

Szukasz IWpfTextViewHost z interaktywnego okna C#? Czy to byłoby dla ciebie w porządku? –

+0

@SimonMourier nie jest pewien. Potrzebuję konkretnej kontroli, która może 1) dać mi cały bufor i 2) powiadomić o wszelkich zmianach. w zasadzie muszę śledzić każdą zmianę w oknie interaktywnym. –

Odpowiedz

10

Oto kod, który dostanie IWpfTextViewHost odwołanie w sprawie C# interaktywnej Oknie. Stamtąd można mieć dostęp do wszystkich usług tekstowych z Visual Studio: linie tekstu, tekstu itp bufora (lub można podłączyć bezpośrednio na kontroli WPF, która nie polecam)

// 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" nie jest specjalnie udokumentowany, ale źródło jest otwarte: http://source.roslyn.io/#Microsoft.VisualStudio.VsInteractiveWindow

+0

Wygląda na to, że może działać! Szybkie pytanie: w jaki sposób mam zamiar podłączyć się do podstawowego kontrolera VS? Powód, o który pytam, to też chciałbym uzyskać informacje o karetce i selekcji. –

+0

Wszystko powinno być dostępne z IWpfTextViewHost i poniżej. Najbardziej interesujące rzeczy znajdują się w ITextView: Caret, Selection, itp. Https://docs.microsoft.com/en-us/dotnet/api/microsoft.visualstudio.text.editor.itextview?view=visualstudiosdk-2017 –

+0

Źródło jest otwarta, dobra odpowiedź! –