我正在尝试在C#扩展中获得active IWpfTextView编辑器。我使用一个小型的MEF服务将视图注入到VSAsyncPackage中。但它不是很可靠--有时注入的视图是错误的(例如从另一个视图)或缺失。以下是服务:
public interface IActiveViewAccessor
{
IWpfTextView? ActiveView { get; }
}
[Export(typeof(IWpfTextViewConnectionListener))]
[Export(typeof(IActiveViewAccessor))]
[ContentType("text")]
[TextViewRole(PredefinedTextViewRoles.Document)]
internal sealed class ActiveViewConnectionListener : IWpfTextViewConnectionListener, IActiveViewAccessor
{
public IWpfTextView? ActiveView { get; private set; }
public void SubjectBuffersConnected(IWpfTextView textView, ConnectionReason reason, Collection<ITextBuffer> subjectBuffers)
{
this.ActiveView = textView;
}
public void SubjectBuffersDisconnected(IWpfTextView textView, ConnectionReason reason, Collection<ITextBuffer> subjectBuffers)
{
this.ActiveView = null;
}
}此服务被注入VSPackage,如下所示:
this.viewAccessor = this.exportProvider.GetExportedValue<IActiveViewAccessor>();它被用作:
var view = this.viewAccessor?.ActiveView;是否有更好和更稳定的方法在异步IWpfTextView中获取VSPackage?
到目前为止,这里有一些相关的问题,但并不完全符合我的预期:
发布于 2020-12-28 15:09:07
经过一些调试和探索,我得出结论,我的最初方法非常幼稚。因为在简单的情况下,IWpfTextViewConnectionListener在每个编辑器窗口只触发一次,而且在已经连接的视图之间切换时不会触发。
在对其进行实验并偷偷进入VsVim > VsAdapter.cs之后,我将IActiveViewAccessor更改为:
public interface IActiveViewAccessor
{
IWpfTextView? ActiveView { get; }
}
[Export(typeof(IActiveViewAccessor))]
internal sealed class ActiveViewAccessor : IActiveViewAccessor
{
private readonly SVsServiceProvider serviceProvider;
private readonly IVsEditorAdaptersFactoryService editorAdaptersFactoryService;
[ImportingConstructor]
public ActiveViewAccessor(
SVsServiceProvider vsServiceProvider,
IVsEditorAdaptersFactoryService editorAdaptersFactoryService)
{
this.serviceProvider = vsServiceProvider;
this.editorAdaptersFactoryService = editorAdaptersFactoryService;
}
public IWpfTextView? ActiveView
{
get
{
IVsTextManager2 textManager =
serviceProvider.GetService<SVsTextManager, IVsTextManager2>();
if (textManager == null)
{
return null;
}
int hr = textManager.GetActiveView2(
fMustHaveFocus: 1,
pBuffer: null,
grfIncludeViewFrameType: (uint)_VIEWFRAMETYPE.vftCodeWindow,
ppView: out IVsTextView vsTextView);
if (ErrorHandler.Failed(hr))
{
return null;
}
return editorAdaptersFactoryService.GetWpfTextView(vsTextView);
}
}
}https://stackoverflow.com/questions/65453407
复制相似问题