Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/20.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
.net WPF物品容器回收_.net_Wpf_Itemscontrol_Recycle_Itemcontainergenerator - Fatal编程技术网

.net WPF物品容器回收

.net WPF物品容器回收,.net,wpf,itemscontrol,recycle,itemcontainergenerator,.net,Wpf,Itemscontrol,Recycle,Itemcontainergenerator,我想实现一个自定义的画布,当用作项目span时,它会回收容器。因此,我从virtualzingpanel派生并覆盖ArrangeOverride和MeasureOverride。我在MeasureOverride中进行生成,如下所示: var children = base.InternalChildren; var itemsControl = ItemsControl.GetItemsOwner(this); var itemsCount = itemsControl.Items.Coun

我想实现一个自定义的
画布
,当用作
项目span
时,它会回收容器。因此,我从
virtualzingpanel
派生并覆盖
ArrangeOverride
MeasureOverride
。我在
MeasureOverride
中进行生成,如下所示:

var children = base.InternalChildren;

var itemsControl = ItemsControl.GetItemsOwner(this);
var itemsCount = itemsControl.Items.Count;

IItemContainerGenerator generator = itemsControl.ItemContainerGenerator;

var startPos = generator.GeneratorPositionFromIndex(0);

using (generator.StartAt(startPos, GeneratorDirection.Forward, true))
{
    for (int i = 0; i < itemsCount; i++)
    {
        bool isNewlyRealized;

        var child = generator.GenerateNext(out isNewlyRealized) as UIElement;

        if (isNewlyRealized)
        {
            base.AddInternalChild(child);
            generator.PrepareItemContainer(child);
        }

        child.Measure(constraint);
    }
}
但它不起作用。你知道怎么做吗?

看看这里:

我通过以下方式进行回收:

OnItemChanged
中,我只调用
RemoveInternalChildRange

protected override void OnItemsChanged(object sender, ItemsChangedEventArgs args)
    {
      switch (args.Action)
      {
        case NotifyCollectionChangedAction.Remove:
        case NotifyCollectionChangedAction.Replace:
          RemoveInternalChildRange(args.Position.Index, args.ItemUICount);
          break;
        case NotifyCollectionChangedAction.Move:
          RemoveInternalChildRange(args.OldPosition.Index, args.ItemUICount);
          break;
      }
    }
在“度量值覆盖”中,我首先添加新项,然后删除旧项。 如果您使用回收,您必须知道,如果您使用的是回收容器,则通过调用GenerateNext获得的新标志也是假的。

在这里,我们添加了新项目:

GeneratorPosition start = ItemContainerGenerator.GeneratorPositionFromIndex(iFirstItemIndex);
      int iChildIndex = (start.Offset == 0) ? start.Index : start.Index + 1;
      using (ItemContainerGenerator.StartAt(start, GeneratorDirection.Forward, true))
      {
        for (int i = iFirstItemIndex; i <= iLastItemIndex; i++, iChildIndex++)
        {
          bool bNew;
          UIElement element = (UIElement)ItemContainerGenerator.GenerateNext(out bNew);
          //If we get a new instance
          if (bNew)
          {
            if (iChildIndex >= Children.Count) AddInternalChild(element);
            else InsertInternalChild(iChildIndex, element);
            ItemContainerGenerator.PrepareItemContainer(element);
          }
          //If we get a recycled element
          else if (!InternalChildren.Contains(element))
          {
            InsertInternalChild(iChildIndex, element);
            ItemContainerGenerator.PrepareItemContainer(element);
          }
          element.Measure(...);
        }
      }
GeneratorPosition start=ItemContainerGenerator.GeneratorPositionFromIndex(iFirstItemIndex);
int iChildIndex=(start.Offset==0)?start.Index:start.Index+1;
使用(ItemContainerGenerator.StartAt(start,GeneratorDirection.Forward,true))
{
对于(int i=iFirstItemIndex;i=Children.Count)AddInternalChild(元素);
else InsertInternalChild(iChildIndex,元素);
ItemContainerGenerator.PrepareItemContainer(元素);
}
//如果我们得到一个可回收的元素
如果(!InternalChildren.Contains(元素))为else
{
InsertInternalChild(iChildIndex,元素);
ItemContainerGenerator.PrepareItemContainer(元素);
}
元素。度量(…);
}
}
添加项目后,我们将删除旧项目:

for (int i = Children.Count - 1; i >= 0; i--)
      {
        GeneratorPosition childGeneratorPosition = new GeneratorPosition(i, 0);
        int iIndex = ItemContainerGenerator.IndexFromGeneratorPosition(childGeneratorPosition);
        if (iIndex < iFirstItemIndex || iIndex > iLastItemIndex)
        {
          //remove() calls ItemContainerGenerator.remove() OR recycle(). Both works.
          remove(childGeneratorPosition, 1);
          RemoveInternalChildRange(i, 1);
        }
      }
for(int i=Children.Count-1;i>=0;i--)
{
GeneratorPosition childGeneratorPosition=新的GeneratorPosition(i,0);
int iIndex=ItemContainerGenerator.IndexFromGeneratorPosition(childGeneratorPosition);
如果(iIndexiLastItemIndex)
{
//remove()调用ItemContainerGenerator.remove()或recycle()。两者都可以工作。
移除(儿童发电机位置,1);
RemoveInternalChildRange(i,1);
}
}

我希望我能帮助您。

事实上,如果您正在回收,您应该在生成新容器之前调用“清理”代码(最后一个代码块)。这是因为您希望在需要可用容器之前而不是之后回收它们。保存一些不需要的创建。链接不再可用。
for (int i = Children.Count - 1; i >= 0; i--)
      {
        GeneratorPosition childGeneratorPosition = new GeneratorPosition(i, 0);
        int iIndex = ItemContainerGenerator.IndexFromGeneratorPosition(childGeneratorPosition);
        if (iIndex < iFirstItemIndex || iIndex > iLastItemIndex)
        {
          //remove() calls ItemContainerGenerator.remove() OR recycle(). Both works.
          remove(childGeneratorPosition, 1);
          RemoveInternalChildRange(i, 1);
        }
      }