首页 > 解决方案 > Xamarin Forms CollectionView 无法正确显示

问题描述

我有个问题。我创建了一个带有自定义 ViewPage 的 CollectionView 来放置具有行跨度的网格。ItemSource 是使用 ViewModel 设置的。现在,当我在 CollectionView 中滚动时,行会随机放置在屏幕上,甚至在彼此之间。

这是我的 xaml 代码:

<CollectionView ItemsSource="{Binding agentOrderList}" Margin="5,0,5,0" HeightRequest="450">
    <CollectionView.ItemsLayout>
        <LinearItemsLayout Orientation="Vertical" ItemSpacing="0"/>
    </CollectionView.ItemsLayout>

    <CollectionView.ItemTemplate>
        <DataTemplate>
            <local:OrderView BindingContext="{Binding }"/>
        </DataTemplate>
    </CollectionView.ItemTemplate>
</CollectionView>

这是视图模型:

public class VM_AgentsPage : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;
    protected void OnPropertyChanged([CallerMemberName] string propertyName = null)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }

    private ObservableCollection<OrderBundle> _agentOrderList;
    public ObservableCollection<OrderBundle> agentOrderList
    {
        get
        {
            return _agentOrderList;
        }
        set
        {
            if (_agentOrderList != value)
            {
                _agentOrderList = value;
                OnPropertyChanged();
            }
        }
    }


    public VM_AgentsPage()
    {
        agentOrderList = new ObservableCollection<OrderBundle>();
        LoadAgentOrders_Handler();
    }


    public Task LoadAgentOrders_Handler()
    {
        return LoadAgentOrders();
    }
    private async Task LoadAgentOrders()
    {
        IsRefreshingAgentOrders = true;

        App.AgentOrderList = await App.RestService.GetAgentOrders(App.AgentId);

        ObservableCollection<OrderBundle> tempAgentOrderList = new ObservableCollection<OrderBundle>();

        foreach (OrderBundle orderBundle in App.AgentOrderList)
        {
            tempAgentOrderList.Add(orderBundle);
        }

        agentOrderList = tempAgentOrderList;

        IsRefreshingAgentOrders = false;
    }
}

最后是 OrderView.xaml.cs:

public partial class OrderView : ContentView
{
    Grid grid;

    public OrderView()
    {
        InitializeComponent();


        grid = new Grid
        {
            ColumnDefinitions =
        {
            new ColumnDefinition{ Width = new GridLength(1, GridUnitType.Star)},
            new ColumnDefinition{ Width = new GridLength(1, GridUnitType.Star) },
            new ColumnDefinition{ Width = new GridLength(1, GridUnitType.Star) },
            new ColumnDefinition{ Width = new GridLength(1, GridUnitType.Star) },
            new ColumnDefinition{ Width = new GridLength(1, GridUnitType.Star) }
        }
        };

        grid.RowSpacing = 0;

        this.Content = grid;


        this.BindingContextChanged += View1_BindingContextChanged;
    }

    private void View1_BindingContextChanged(object sender, EventArgs e)
    {
        var obj = this.BindingContext as OrderBundles;

        if (obj != null)
        {
            List<Trade> list = obj.Trades;

            for(int i = 0; i < list.Count; i++)
            {

                grid.RowDefinitions.Add(new RowDefinition { Height = new GridLength(20) });

                Trade trade = list[i];
                grid.Children.Add(new Label
                {
                    Text = trade.Date
                }, 0, i);
                grid.Children.Add(new Label
                {
                    Text = trade.Action
                }, 1, i);
                grid.Children.Add(new Label
                {
                    Text = trade.Coin
                }, 2, i);
                grid.Children.Add(new Label
                {
                    Text = trade.Price.ToString()
                }, 3, i);              
            }

            Label label = new Label
            {
                Text = list[0].ProfitUSDT,
                TextColor = Color.Green ,
                VerticalTextAlignment = TextAlignment.Center
            };

            grid.Children.Add(label, 4, 0);


            Grid.SetRowSpan(label, list.Count);
        }
    }
}

这是它一开始的样子: 在此处输入图像描述

但是当我滚动它开始看起来像这样: 在此处输入图像描述

这是什么原因造成的?

标签: c#xamarinxamarin.formsxamarin.androidxamarin.ios

解决方案


我发现BindingContextChanged滚动collectionview的时候触发了方法,所以一直在添加RowDefinition和控制,我们应该在开始时清除列表。

    private void View1_BindingContextChanged(object sender, EventArgs e)
    {
        //add the following two lines
        grid.RowDefinitions.Clear();
        grid.Children.Clear();

在此处输入图像描述


推荐阅读