我正在创建从WPF OverflowPanel
类派生的Panel
。目的是在单个方向上填充项目,并且当要显示的项目太多时,多余的项目将被删除,并用另一个控件代替以保持溢出。想一想网站的面包屑,或Windows File Explorer中的地址栏。这是一个.Net Core 3 / C#8项目。
我有一个部分可行的解决方案:我继承自Panel
,并覆盖了MeasureOverride()
和ArrangeOverride()
以获取所需的行为。我现在的问题是要显示一个按钮或其他控件来代替要删除的项目。
我最初的天真方法是在代码中创建一个Button
并尝试对其进行度量/排列。
public class OverflowPanel : Panel
{
// First by itself,but I did also try to host this in a new UIElementCollection
private readonly Button _overflowButton = new Button();
public override Size MeasureOverride(Size availableSize)
{
...
_overflowButton.Measure(availableSize);
// Do stuff with _overflowButton.DerivedSize.
...
}
// Also attempted to draw int in ArrangeOverride()
}
这个 did 给我非零的测量结果。 (我在按钮中放入了一些虚拟内容。)我的算法为我在屏幕上应该放置按钮的位置留了空间,但是在那里什么也没有呈现。
我还通过检查Visual Studio中的Live Visual Tree,确认没有简单的按钮绘制没有视觉样式。
我尝试制作一个UIElementCollection
并向其添加按钮,以查看是否会将其添加到可视化树中,但这还是行不通的。
我见过的大多数Google / StackOverflow结果都暗示了一些类似this.Children.Add(_overflowButton)
的问题,但是当托管在ItemsControl中时,这是行不通的,因为它接管了对象的集合并在您引发异常时尝试弄乱它。
在深入研究Panel
和UIElementCollection
的代码之后,我注意到Panel允许您覆盖
UIElementCollection CreateUIElementCollection(FrameworkElement logicalParent)
使用UIElemenetCollection
的派生实现。我创建了PinningUIElementCollection
来欺骗WPF渲染额外的元素。它存储了额外的项目,然后在访问迭代器时将它们放进去。它还进行索引修改以访问额外的项目集合和自动生成的项目。
这确实有效。现在显示了我的按钮(尽管样式不正确,但这是一个单独的问题。)
但是,我对这种方法的看法是,这似乎是一项很多的工作。似乎也容易出错:当它尝试使用数字索引时,我很容易会错过它而忘记处理它,从而导致不可预测的结果。
在派生的Panel实现中,是否有一种更简单/更直接的方法来显示一个额外的按钮或一些其他任意控件而只减少了几圈?