Próbuję utworzyć formant wykresu przy użyciu listwy listy WPF. Stworzyłem własne płótno, które pochodzi z VirtualizingPanel, a ja sam zajmuję się realizacją i wirtualizacją przedmiotów.Wirtualizacja WPF Listbox tworzy DisconnectedItems
Panel elementów "listbox" zostanie ustawiony jako moje niestandardowe płótno zwirtualizowane.
Problem mam napotykając występuje w następującym scenariuszu:
- ListBox Pozycja A tworzony jest pierwszy.
- ListBox Pozycja B jest tworzona na prawo od pozycji A na płótnie.
- Element ListBox jest najpierw zwirtualizowany (poprzez przesunięcie go poza obszar widoku).
- ListBox Pozycja B jest zwirtualizowana jako druga (ponownie poprzez przesunięcie jej poza obszar widoku).
- Doprowadzić ListBox pozycja A i B w związku (tj zrealizować je)
- Korzystanie Snoop, wykryć, że ListBox ma teraz 3 elementów, jednym z nich jest to „DisconnectedItem” znajdujący się bezpośrednio pod ListBox Pozycja B.
Co powoduje utworzenie "DisconnectedItem"? Gdybym najpierw wirtualizował B, a następnie A, ten element nie zostałby utworzony. Moja teoria mówi, że wirtualizacja elementów, które poprzedza inne elementy ListBox, powoduje, że dzieci są odłączone.
Problem jest jeszcze bardziej widoczny za pomocą wykresu z setkami węzłów, ponieważ kończę z setkami rozłączonych elementów podczas przesuwania.
Oto fragment kodu na płótnie:
/// <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));
}
Czy recyklingujesz pojemnik? – Paparazzi
@Blam: Nie sądzę, że jestem, co masz na myśli przez recykling pojemnika? –
Po prostu wyszukaj msdn na pojemnik na recykling http://msdn.microsoft.com/en-us/library/system.windows.controls.virtualizationmode.aspx Wystarczy zasięg, ale także tylko komentarz – Paparazzi