装饰层(VSIX)中的文本输入和焦点

问题描述 投票:0回答:1

我正在制作一个具有内联差异视图功能的 Visual Studio IDE 扩展。

我用

CreateDifferenceView
创建了一个
FrameWorkElement
,要注意这个方法会创建两个内部的
IWpfTextView
。然后我使用
AddAdornment
将其附加到
IWpfTextView

问题是装饰无法正确接收键盘焦点。最初,我可以输入它,但是像 CTRL+ACTRL+C 等命令...不起作用,它们将由主机

IWpfTextView
接收/处理,而不是由主机接收/处理。装饰品。

这个博客学习,我已经通过使用

AddCommandFilter
成功地实现了该工作,并将命令转发到由
IVsTextView
创建的内部
CreateDifferenceView

现在键盘命令可以正常工作,但仍然存在一个问题,装饰仍然没有获得正确的焦点。您可以看到,虽然我可以选择装饰中的文本,但选择仍然显示为“失焦”灰色,并且即使我单击主机

IWpfTextView
也不会失去其选择焦点。装饰品。抱歉,我必须附上 GIF,但没有更好的方法来描述问题。:


我尝试过的:

MRE(

MefProvider
仅导入这些组件):

var docview = await VS.Documents.GetActiveDocumentViewAsync();
var contentType = docview.TextBuffer.ContentType;

var leftBuffer = MefProvider.TextBufferFactoryService.CreateTextBuffer("left content", contentType);
var rightBuffer = MefProvider.TextBufferFactoryService.CreateTextBuffer("right content", contentType);

var diffBuffer = MefProvider.DifferenceBufferFactory.CreateDifferenceBuffer(leftBuffer, rightBuffer);
var diffViewer = MefProvider.DifferenceViewerFactory.CreateDifferenceView(diffBuffer);

var adornmentLayer = docview.TextView.GetAdornmentLayer("MyAdornmentLayer");
adornmentLayer.AddAdornment(AdornmentPositioningBehavior.OwnerControlled, null, null, diffViewer.VisualElement, null);
c# wpf visual-studio-extensions vsix adornment
1个回答
0
投票

解决方法是使用

Microsoft.VisualStudio.Platform.VSEditor.dll
中未记录的内部函数:

diffViewer.VisualElement.GotFocus += (o, e) => {
    AggregateFocusInterceptor.SetInterceptsAggregateFocus(hostView as DependencyObject, true);
};

diffViewer.VisualElement.LostFocus += (o, e) => {
    AggregateFocusInterceptor.SetInterceptsAggregateFocus(hostView as DependencyObject, false);
};

在尝试此操作之前,我通过获取装饰文本视图的

ISpaceReservationManager
然后向其添加代理并触发其
GotFocus
事件来获得部分成功的结果。从技术上讲,这应该可行,但是,在装饰文本视图获得焦点后,主视图就会夺回焦点。我怀疑这可能与触发事件的顺序有关。

不接受这作为答案,因为这只是一种解决方法,应该有更正确的方法来做到这一点。

© www.soinside.com 2019 - 2024. All rights reserved.