Exemple #1
0
        /// <summary>
        /// Gets the actual item template size, using a non-databound materialized
        /// view of the template.
        /// </summary>
        /// <param name="dataTemplate">A data template</param>
        /// <returns>The actual size of the template</returns>
        private CGSize GetTemplateSize(DataTemplate dataTemplate, NSString elementKind)
        {
            //TODO: this should take an available breadth
            CGSize size;

            // Cache the sizes to avoid creating new templates everytime.
            if (!_templateCache.TryGetValue(dataTemplate ?? _nullDataTemplateKey, out size))
            {
                var container = CreateContainerForElementKind(elementKind);

                // Force a null DataContext so the parent's value does not flow
                // through when temporarily adding the container to Owner.XamlParent
                container.SetValue(FrameworkElement.DataContextProperty, null);

                Style style = null;
                if (elementKind == NativeListViewBase.ListViewItemElementKind)
                {
                    style = Owner.ItemContainerStyle;
                }
                else if (elementKind == NativeListViewBase.ListViewSectionHeaderElementKind)
                {
                    style = Owner.GroupStyle?.HeaderContainerStyle;
                }
                if (style != null)
                {
                    container.Style = style;
                }

                container.ContentTemplate = dataTemplate;
                try
                {
                    // Attach templated container to visual tree while measuring. This works around the bug that default Style is not
                    // applied until view is loaded.
                    Owner.XamlParent.AddSubview(BlockLayout);
                    BlockLayout.AddSubview(container);
                    // Measure with PositiveInfinity rather than MaxValue, since some views handle this better.
                    size = Owner.NativeLayout.Layouter.MeasureChild(container, new Size(double.PositiveInfinity, double.PositiveInfinity));

                    if ((size.Height > nfloat.MaxValue / 2 || size.Width > nfloat.MaxValue / 2) &&
                        this.Log().IsEnabled(LogLevel.Warning)
                        )
                    {
                        this.Log().LogWarning($"Infinite item size reported, this can crash {nameof(UICollectionView)}.");
                    }
                }
                finally
                {
                    Owner.XamlParent.RemoveChild(BlockLayout);
                    BlockLayout.RemoveChild(container);

                    // Reset the DataContext for reuse.
                    container.ClearValue(FrameworkElement.DataContextProperty);
                }

                _templateCache[dataTemplate ?? _nullDataTemplateKey] = size;
            }

            return(size);
        }
Exemple #2
0
        /// <summary>
        /// Gets the actual item template size, using a non-databound materialized
        /// view of the template.
        /// </summary>
        /// <param name="dataTemplate">A data template</param>
        /// <returns>The actual size of the template</returns>
        private CGSize GetTemplateSize(DataTemplate dataTemplate, NSString elementKind)
        {
            //TODO: this should take an available breadth
            CGSize size;

            // Cache the sizes to avoid creating new templates everytime.
            if (!_templateCache.TryGetValue(dataTemplate ?? _nullDataTemplateKey, out size))
            {
                var container = CreateContainerForElementKind(elementKind);

                Style style = null;
                if (elementKind == NativeListViewBase.ListViewItemElementKind)
                {
                    style = Owner.ItemContainerStyle;
                }
                else if (elementKind == NativeListViewBase.ListViewSectionHeaderElementKind)
                {
                    style = Owner.GroupStyle?.HeaderContainerStyle;
                }
                if (style != null)
                {
                    container.Style = style;
                }

                container.ContentTemplate = dataTemplate;
                try
                {
                    // Attach templated container to visual tree while measuring. This works around the bug that default Style is not
                    // applied until view is loaded.
                    Owner.XamlParent.AddSubview(BlockLayout);
                    BlockLayout.AddSubview(container);
                    size = Owner.NativeLayout.Layouter.MeasureChild(container, new Size(double.MaxValue, double.MaxValue));

                    if ((size.Height > nfloat.MaxValue / 2 || size.Width > nfloat.MaxValue / 2) &&
                        this.Log().IsEnabled(LogLevel.Warning)
                        )
                    {
                        this.Log().LogWarning($"Infinite item size reported, this can crash {nameof(UICollectionView)}.");
                    }
                }
                finally
                {
                    Owner.XamlParent.RemoveChild(BlockLayout);
                    BlockLayout.RemoveChild(container);
                }

                _templateCache[dataTemplate ?? _nullDataTemplateKey] = size;
            }

            return(size);
        }