如何在 ScrollViewer 中获得 Adorner 与其装饰元素的一对一匹配?
Posted
技术标签:
【中文标题】如何在 ScrollViewer 中获得 Adorner 与其装饰元素的一对一匹配?【英文标题】:How to get a one-to-one match of an Adorner with its adorned element within a ScrollViewer? 【发布时间】:2017-04-26 16:55:05 【问题描述】:wpf
我在 ScrollViewer 的 Grid 中有一个控件 A(一个 inkcanvas)。控件 A 比物理窗口高,因此 ScrollViewer 正确添加了垂直滚动条,向下滚动可以查看整个控件。将带有控件 B 的装饰器(另一个 inkcanvas)附加到控件 A 时,向下滚动会在屏幕底部显示要切断的装饰器。也就是说,Adorner 没有完全覆盖被装饰的元素和/或在滚动时没有向下延伸。
如何让 Adorner(控件)完全覆盖被装饰的元素并尊重 ScrollViewer。 (我需要在 Adorner 控件的像素和 ScrollViewer 中的装饰元素之间进行一对一的匹配)。
TIA
Edit#1:Adorner 中设置 InkCanvas 背景的关键行是
_inkcanvas.Background = CreateGrid();
public InkCanvasTextAdorner(InkCanvas element)
: base(element)
_element = element;
_visuals = new VisualCollection(this);
_inkcanvas = new InkCanvas();
_inkcanvas.Background = CreateGrid();
_visuals.Add(_inkcanvas);
AdornerLayer adornerLayer = AdornerLayer.GetAdornerLayer(element);
adornerLayer.Add(this);
如果使用 InkCanvas(如上所述),则 Adorner 的 背景 会在底部被剪裁。但是,装饰器控件确实会继续到被装饰元素的底部。
但是,如果使用 Canvas 而不是 InkCanvas,则 Adorner 的 背景 会延伸到被装饰元素的底部。
怎么了?
【问题讨论】:
【参考方案1】:我猜测 Background 属性的差异通过 Canvas 而不是 InkCanvas 扩展到物理屏幕可能是因为 Canvas 继承自 Panel 而 InkCanvas 没有。根据发现 Canvas 背景确实可以满足我的需要,我发现下面的代码确实实现了我想要的功能 - 画布允许看到来自其下方图层的图像,但发布了一个网格线,InkCanvas 将在该网格上接受笔划。一切都很好:)
public InkCanvasTextAdorner(InkCanvas element)
: base(element)
_element = element;
// The VisualCollection has only one visual parent. I.e. InkCanvasTextAdorner is the parent to the VisualCollection.
// By overriding default rendering behavior of the VisualCollection, any kind of control and its children can be placed in the Adorner.
_visuals = new VisualCollection(this);
_inkcanvas = new InkCanvas();
_inkcanvas.Background = Brushes.Transparent;
_canvas = new Canvas();
_canvas.Background = CreateGrid();
_grid = new Grid();
_grid.Children.Add(_canvas);
_grid.Children.Add(_inkcanvas);
// The _grid is a logical child of the VisualCollection of the Adorner. The ArrangeOverride and MeasureOverride will set up the Grid control.
_visuals.Add(_grid); // Adding a single control for display.
// AdornerLayer adornerLayer = AdornerLayer.GetAdornerLayer(element);
AdornerLayer adornerLayer = AdornerLayer.GetAdornerLayer(element);
adornerLayer.Add(this);
看起来像:
【讨论】:
以上是关于如何在 ScrollViewer 中获得 Adorner 与其装饰元素的一对一匹配?的主要内容,如果未能解决你的问题,请参考以下文章
如何在 ScrollViewer (ListView) 中查找项目的位置?