Xamarin Forms CollectionView doesn't show properly

廉价感情. 提交于 2020-06-17 09:32:48

问题


I have a problem. I created a CollectionView with a custom ViewPage to place a grid with rowspan. The ItemSource is set using a ViewModel. Now when I scroll in the CollectionView the rows are randomly placed on the screen, even inside each other.

Here is my xaml code:

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

Here is the ViewModel:

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

And finally the 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);
        }
    }
}

This is what it looks like in the beginning:

But when I scroll it starts looking like this:

What is causing this?


回答1:


I found BindingContextChanged method triggers when scroll the collectionview , so it keeps adding RowDefinition and controls , we should clear the list at the beginning .

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



来源:https://stackoverflow.com/questions/62242329/xamarin-forms-collectionview-doesnt-show-properly

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!