C# 如何在VS2019扩展(MEF)中获取活动的IWpfTextView
我正在尝试在VS2019扩展中获取活动的C#编辑器IWpfTextView。我正在使用一个小型MEF服务将视图注入到VSAsyncPackage中。但它不是很可靠-有时注入的视图是错误的(例如,从另一个视图)或丢失的。服务内容如下:C# 如何在VS2019扩展(MEF)中获取活动的IWpfTextView,c#,visual-studio-2019,mef,visual-studio-extensions,C#,Visual Studio 2019,Mef,Visual Studio Extensions,我正在尝试在VS2019扩展中获取活动的C#编辑器IWpfTextView。我正在使用一个小型MEF服务将视图注入到VSAsyncPackage中。但它不是很可靠-有时注入的视图是错误的(例如,从另一个视图)或丢失的。服务内容如下: 公共接口IActiveViewAccessor { IWpfTextView?活动视图{get;} } [导出(类型(IWPTextViewConnectionListener))] [导出(类型(IActiveViewAccessor))] [内容类型(“文本”)
公共接口IActiveViewAccessor
{
IWpfTextView?活动视图{get;}
}
[导出(类型(IWPTextViewConnectionListener))]
[导出(类型(IActiveViewAccessor))]
[内容类型(“文本”)]
[TextViewRole(预定义的textViewRoles.Document)]
内部密封类ActiveViewConnectionListener:IWpfTextViewConnectionListener,IActiveViewAccessor
{
公共IWPTextView?活动视图{get;私有集;}
public void subjectBuffers已连接(IWPTextView textView、ConnectionReason、Collection subjectBuffers)
{
this.ActiveView=textView;
}
public void subjectBuffers断开连接(IWPTextView textView、ConnectionReason、Collection subjectBuffers)
{
this.ActiveView=null;
}
}
此服务将作为以下内容注入VSPackage:
this.viewAccessor=this.exportProvider.GetExportedValue();
它被用作:
var view=this.viewAccessor?.ActiveView;
有没有更好、更稳定的方法可以在异步VSPackage中获取IWpfTextView
到目前为止,这里有一些相关的问题,但并不完全是我所期望的:
经过一点调试和探索,我认为我最初的方法非常幼稚。因为在一个简单的情况下,
IWpfTextViewConnectionListener在每个编辑器窗口中只触发一次,并且在已经连接的视图之间切换时不会触发
在使用它进行实验并潜入系统后,我将IActiveViewAccessor
更改为:
公共接口IActiveViewAccessor
{
IWpfTextView?活动视图{get;}
}
[导出(类型(IActiveViewAccessor))]
内部密封类ActiveViewAccessor:IActiveViewAccessor
{
专用只读SVsServiceProvider服务提供商;
专用只读IVSEditorAdapterFactoryService编辑器适配器FactoryService;
[导入构造函数]
公共ActiveViewAccessor(
SVsServiceProvider vsServiceProvider,
IVSEditor适配器工厂服务编辑器适配器工厂服务)
{
this.serviceProvider=vsServiceProvider;
this.editorAdaptersFactoryService=editorAdaptersFactoryService;
}
公共IWpfTextView?活动视图
{
得到
{
IVsTextManager2文本管理器=
serviceProvider.GetService();
if(textManager==null)
{
返回null;
}
int hr=textManager.GetActiveView2(
fMustHaveFocus:1,
pBuffer:null,
grfIncludeViewFrameType:(uint)\u VIEWFRAMETYPE.vftdewindow,
ppView:out-IVsTextView-vsTextView);
if(ErrorHandler.Failed(hr))
{
返回null;
}
返回editorAdaptersFactoryService.GetWpfTextView(vsTextView);
}
}
}
经过一点调试和探索,我认为我最初的方法非常幼稚。因为在一个简单的情况下,IWpfTextViewConnectionListener在每个编辑器窗口中只触发一次,并且在已经连接的视图之间切换时不会触发
在使用它进行实验并潜入系统后,我将IActiveViewAccessor
更改为:
公共接口IActiveViewAccessor
{
IWpfTextView?活动视图{get;}
}
[导出(类型(IActiveViewAccessor))]
内部密封类ActiveViewAccessor:IActiveViewAccessor
{
专用只读SVsServiceProvider服务提供商;
专用只读IVSEditorAdapterFactoryService编辑器适配器FactoryService;
[导入构造函数]
公共ActiveViewAccessor(
SVsServiceProvider vsServiceProvider,
IVSEditor适配器工厂服务编辑器适配器工厂服务)
{
this.serviceProvider=vsServiceProvider;
this.editorAdaptersFactoryService=editorAdaptersFactoryService;
}
公共IWpfTextView?活动视图
{
得到
{
IVsTextManager2文本管理器=
serviceProvider.GetService();
if(textManager==null)
{
返回null;
}
int hr=textManager.GetActiveView2(
fMustHaveFocus:1,
pBuffer:null,
grfIncludeViewFrameType:(uint)\u VIEWFRAMETYPE.vftdewindow,
ppView:out-IVsTextView-vsTextView);
if(ErrorHandler.Failed(hr))
{
返回null;
}
返回editorAdaptersFactoryService.GetWpfTextView(vsTextView);
}
}
}
我建议您可以添加关于您的提示的答案,而不是在问题中。@PerryQian MSFT我不完全确定访问活动IWpfTextView的“现代”或“正确”方式,但您的建议很有意义,谢谢。完成。我建议您可以添加有关提示的答案,而不是在问题中。@PerryQian MSFT我不完全确定访问活动IWpfTextView的“现代”或“正确”方式,但您的建议是有意义的,谢谢。完成。