gpt4 book ai didi

c# - WPF 列表框虚拟化创建 DisconnectedItems

转载 作者:可可西里 更新时间:2023-11-01 08:10:38 28 4
gpt4 key购买 nike

我正在尝试使用 WPF 列表框创建图形控件。我创建了自己的 Canvas,它派生自 VirtualizingPanel,我自己处理项目的实现和虚拟化。

然后将列表框的项目面板设置为我的自定义虚拟 Canvas 。

我遇到的问题发生在以下场景:

  • 首先创建列表框项 A。
  • ListBox 项目 B 创建在 Canvas 上项目 A 的右侧。
  • ListBox Item A 首先被虚拟化(通过将其平移出 View )。
  • ListBox Item B 第二个被虚拟化(再次通过将其平移到 View 之外)。
  • 将 ListBox 项 A 和 B 置于 View 中(即:实现它们)
  • 使用 Snoop,我检测到 ListBox 现在有 3 个项目,其中之一是“DisconnectedItem”,位于 ListBox 项目 B 的正下方。

是什么原因导致创建此“DisconnectedItem”?如果我先虚拟化 B,然后再虚拟化 A,则不会创建此项目。我的理论是,虚拟化 ListBox 中位于其他项目之前的项目会导致子项断开连接。

使用具有数百个节点的图表时,问题更加明显,因为我在四处移动时最终得到数百个断开连接的项目。

这是 Canvas 的部分代码:

/// <summary>
/// Arranges and virtualizes child element positionned explicitly.
/// </summary>
public class VirtualizingCanvas : VirtualizingPanel
{
(...)

protected override Size MeasureOverride(Size constraint)
{
ItemsControl itemsOwner = ItemsControl.GetItemsOwner(this);

// For some reason you have to "touch" the children collection in
// order for the ItemContainerGenerator to initialize properly.
var necessaryChidrenTouch = Children;

IItemContainerGenerator generator = ItemContainerGenerator;

IDisposable generationAction = null;

int index = 0;
Rect visibilityRect = new Rect(
-HorizontalOffset / ZoomFactor,
-VerticalOffset / ZoomFactor,
ActualWidth / ZoomFactor,
ActualHeight / ZoomFactor);

// Loop thru the list of items and generate their container
// if they are included in the current visible view.
foreach (object item in itemsOwner.Items)
{
var virtualizedItem = item as IVirtualizingCanvasItem;

if (virtualizedItem == null ||
visibilityRect.IntersectsWith(GetBounds(virtualizedItem)))
{
if (generationAction == null)
{
GeneratorPosition startPosition =
generator.GeneratorPositionFromIndex(index);
generationAction = generator.StartAt(startPosition,
GeneratorDirection.Forward, true);
}

GenerateItem(index);
}
else
{
GeneratorPosition itemPosition =
generator.GeneratorPositionFromIndex(index);

if (itemPosition.Index != -1 && itemPosition.Offset == 0)
{
RemoveInternalChildRange(index, 1);
generator.Remove(itemPosition, 1);
}

// The generator needs to be "reseted" when we skip some items
// in the sequence...
if (generationAction != null)
{
generationAction.Dispose();
generationAction = null;
}
}

++index;
}

if (generationAction != null)
{
generationAction.Dispose();
}

return default(Size);
}

(...)

private void GenerateItem(int index)
{
bool newlyRealized;
var element =
ItemContainerGenerator.GenerateNext(out newlyRealized) as UIElement;

if (newlyRealized)
{
if (index >= InternalChildren.Count)
{
AddInternalChild(element);
}
else
{
InsertInternalChild(index, element);
}

ItemContainerGenerator.PrepareItemContainer(element);

element.RenderTransform = _scaleTransform;
}

element.Measure(new Size(double.PositiveInfinity,
double.PositiveInfinity));
}

最佳答案

我迟到了 6 年,但问题仍未在 WPF 中修复。 Here是解决方案(解决方法)。

对 DataContext 进行自绑定(bind),例如:

<Image DataContext="{Binding}" />

这对我有用,即使对于非常复杂的 xaml。

关于c# - WPF 列表框虚拟化创建 DisconnectedItems,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14282894/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com