|
|
@@ -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;
|