|
|
|
@ -526,43 +526,60 @@ namespace Avalonia.Controls |
|
|
|
return element; |
|
|
|
} |
|
|
|
|
|
|
|
// There are several cases handled here with respect to which element gets returned and when DataContext is modified.
|
|
|
|
//
|
|
|
|
// 1. If there is no ItemTemplate:
|
|
|
|
// 1.1 If data is an IControl -> the data is returned
|
|
|
|
// 1.2 If data is not an IControl -> a default DataTemplate is used to fetch element and DataContext is set to data
|
|
|
|
//
|
|
|
|
// 2. If there is an ItemTemplate:
|
|
|
|
// 2.1 If data is not an IControl -> Element is fetched from ElementFactory and DataContext is set to the data
|
|
|
|
// 2.2 If data is an IControl:
|
|
|
|
// 2.2.1 If Element returned by the ElementFactory is the same as the data -> Element (a.k.a. data) is returned as is
|
|
|
|
// 2.2.2 If Element returned by the ElementFactory is not the same as the data
|
|
|
|
// -> Element that is fetched from the ElementFactory is returned and
|
|
|
|
// DataContext is set to the data's DataContext (if it exists), otherwise it is set to the data itself
|
|
|
|
private IControl GetElementFromElementFactory(int index) |
|
|
|
{ |
|
|
|
// The view generator is the provider of last resort.
|
|
|
|
var data = _owner.ItemsSourceView.GetAt(index); |
|
|
|
var itemTemplateFactory = _owner.ItemTemplateShim; |
|
|
|
IControl element = null; |
|
|
|
var itemsSourceContainsElements = false; |
|
|
|
var providedElementFactory = _owner.ItemTemplateShim; |
|
|
|
|
|
|
|
if (itemTemplateFactory == null) |
|
|
|
ItemTemplateWrapper GetElementFactory() |
|
|
|
{ |
|
|
|
element = data as IControl; |
|
|
|
if (providedElementFactory == null) |
|
|
|
{ |
|
|
|
var factory = FuncDataTemplate.Default; |
|
|
|
_owner.ItemTemplate = factory; |
|
|
|
return _owner.ItemTemplateShim; |
|
|
|
} |
|
|
|
|
|
|
|
// No item template provided and ItemsSource contains objects derived from UIElement.
|
|
|
|
// In this case, just use the data directly as elements.
|
|
|
|
itemsSourceContainsElements = element != null; |
|
|
|
return providedElementFactory; |
|
|
|
} |
|
|
|
|
|
|
|
if (element == null) |
|
|
|
IControl GetElement() |
|
|
|
{ |
|
|
|
if (itemTemplateFactory == null) |
|
|
|
if (providedElementFactory == null) |
|
|
|
{ |
|
|
|
// If no ItemTemplate was provided, use a default
|
|
|
|
var factory = FuncDataTemplate.Default; |
|
|
|
_owner.ItemTemplate = factory; |
|
|
|
itemTemplateFactory = _owner.ItemTemplateShim; |
|
|
|
if (data is IControl dataAsElement) |
|
|
|
{ |
|
|
|
return dataAsElement; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
element = itemTemplateFactory.GetElement(_owner, data); |
|
|
|
var elementFactory = GetElementFactory(); |
|
|
|
return elementFactory.GetElement(_owner, data); |
|
|
|
} |
|
|
|
|
|
|
|
var element = GetElement(); |
|
|
|
|
|
|
|
var virtInfo = ItemsRepeater.TryGetVirtualizationInfo(element); |
|
|
|
if (virtInfo == null) |
|
|
|
{ |
|
|
|
virtInfo = ItemsRepeater.CreateAndInitializeVirtualizationInfo(element); |
|
|
|
} |
|
|
|
|
|
|
|
if (!itemsSourceContainsElements) |
|
|
|
if (data != element) |
|
|
|
{ |
|
|
|
// Prepare the element
|
|
|
|
element.DataContext = data; |
|
|
|
|