在添加子对象的同时锁定Grid上的视觉更新

时间:2018-07-29 19:54:49

标签: xamarin.forms

当我将子(单元格)添加到网格中时,可以看到网格中添加了行和列。 起初看起来很酷,但它使应用程序的运行速度看起来很慢。

因此,我想知道是否有一种方法可以锁定视觉更新,希望这也可以更快地填充网格。

谢谢您的任何建议。

1 个答案:

答案 0 :(得分:0)

我认为这里的布局计算不是问题-它是第一次渲染,涉及太多步骤,例如分配渲染器以及所有可能导致延迟的步骤。可视树越大,得到的效果越差。

您可以尝试将GridParent分离,进行更新,然后将其重新添加到预期的父项中(这应确保渲染更新已暂停)。

//first detach from visual tree
var parent = currentGrid.Parent as ContentView;
parent.Conent = null;

//do your updates to grid control here

//now attach it back to visual tree
parent.Content = currentGrid;

另一个选择是(如@ orhtej2所述)扩展您的Grid控件以暂停布局计算。不确定是否会有助于渲染性能。

public class SmartGrid : Grid
{
    public static readonly BindableProperty SuspendLayoutProperty =
        BindableProperty.Create(
        "SuspendLayout", typeof(bool), typeof(SmartGrid),
        defaultValue: default(bool), propertyChanged: OnSuspendLayoutChanged);

    public bool SuspendLayout
    {
        get { return (bool)GetValue(SuspendLayoutProperty); }
        set { SetValue(SuspendLayoutProperty, value); }
    }

    static void OnSuspendLayoutChanged(BindableObject bindable, object oldValue, object newValue)
    {
        ((SmartGrid)bindable).OnSuspendLayoutChangedImpl((bool)oldValue, (bool)newValue);
    }

    protected virtual void OnSuspendLayoutChangedImpl(bool oldValue, bool newValue)
    {
        InvalidateLayout();
    }

    protected override void InvalidateLayout()
    {
        if(!SuspendLayout)
            base.InvalidateLayout();
    }

    protected override void InvalidateMeasure()
    {
        if (!SuspendLayout)
            base.InvalidateMeasure();
    }

    protected override void LayoutChildren(double x, double y, double width, double height)
    {
        if (!SuspendLayout)
            base.LayoutChildren(x, y, width, height);
    }
}

示例用法如下:

//first detach from visual tree
var parent = currentGrid.Parent as ContentView;
parent.Conent = null;

currentGrid.SuspendLayout = true;
//do your updates to grid control here
currentGrid.SuspendLayout = false;

//now attach it back to visual tree
parent.Content = currentGrid;