internal DependencyObject GenerateNext (out bool isNewlyRealized)
{
int index;
// This is relative to the realised elements.
int startAt = GenerationState.Position.Index;
if (startAt == -1) {
if (GenerationState.Position.Offset < 0)
index = Owner.Items.Count + GenerationState.Position.Offset;
else if (GenerationState.Position.Offset == 0)
index = 0;
else
index = GenerationState.Position.Offset - 1;
} else if (startAt >= 0 && startAt < RealizedElements.Count) {
// We're starting relative to an already realised element
index = RealizedElements [startAt] + GenerationState.Position.Offset;
} else {
index = -1;
}
bool alreadyRealized = RealizedElements.Contains (index);
if (!GenerationState.AllowStartAtRealizedItem && alreadyRealized && GenerationState.Position.Offset == 0) {
index += GenerationState.Step;
alreadyRealized = RealizedElements.Contains (index);
}
if (index < 0 || index >= Owner.Items.Count) {
isNewlyRealized = false;
return null;
}
if (alreadyRealized) {
GenerationState.Position = new GeneratorPosition (RealizedElements.IndexOf (index), GenerationState.Step);
isNewlyRealized = false;
return ContainerIndexMap [index];
}
DependencyObject container;
var item = Owner.Items [index];
if (Owner.IsItemItsOwnContainer (item)) {
container = (DependencyObject) item;
isNewlyRealized = true;
} else {
if (Cache.Count == 0) {
container = Owner.GetContainerForItem ();
isNewlyRealized = true;
} else {
container = Cache.Dequeue ();
isNewlyRealized = false;
}
ContentControl c = container as ContentControl;
if (c != null)
c.ContentSetsParent = false;
}
FrameworkElement f = container as FrameworkElement;
if (f != null && !(item is UIElement))
f.DataContext = item;
RealizedElements.Add (index);
ContainerIndexMap.Add (container, index);
DependencyObject cc;
ContainerItemMap.Add (container, item);
GenerationState.Position = new GeneratorPosition (RealizedElements.IndexOf (index), GenerationState.Step);
return container;
}