CollectionView — проблема при программном обновлении ItemsLayout

#xamarin #xamarin.forms #xamarin.ios #uicollectionview #xamarin.ios-binding

#xamarin #xamarin.forms #xamarin.ios #uicollectionview #xamarin.ios-привязка

Вопрос:

Я обновляю CollectionView.ItemsLayout программно после привязки источника элемента, и он отлично работает на Android, но не на iOS. Приложение iOS не выдает никаких исключений / ошибок, но приложение зависает, и когда я смотрю на окно вывода, я получаю сообщение ниже:

Попытка обновить информацию о макете была обнаружена уже в процессе вычисления макета (т. Е. повторного вызова). Это приведет к неожиданному поведению или сбою. Это может произойти, если при вызове делегата запускается передача макета. Экземпляр UICollectionViewFlowLayout является (<Xamarin_Forms_Platform_iOS_GridViewLayout: 0x7fb2940ec010>)

Попытка подготовить макет, в то время как вызов prepareLayout уже выполнялся (т. Е. повторный вызов), была проигнорирована. Пожалуйста, сообщите об ошибке. Экземпляр UICollectionView равен (<UICollectionView: 0x7f9e68a73000; frame = (0 0; 355 360); clipsToBounds = YES; авторазмер = W H; Распознаватели жестов = <NSArray: 0x600003039c20>; layer = <CALayer: 0x600007e6e180>; contentOffset: {0, 0}; contentSize: { 1, 0}; Скорректированный набор содержимого: {0, 0, 0, 0}; макет: <Xamarin_Forms_Platform_iOS_GridViewLayout: 0x7f9e647972e0>; Источник данных: <Xamarin_Forms_Platform_iOS_GroupableItemsViewController_1: 0x7f9e64797940>>)

Мой XAML:

    <ScrollView>
        <StackLayout Margin="0,0,5,0">
            <Label x:Name="NoItemLabel" IsVisible="False"
               Text="{languages:Translate EmptyListMessage}"
               Style="{DynamicResource NoItemListLabel}" />

            <!--  Product List  -->
            <CollectionView 
                VerticalScrollBarVisibility="Never" VerticalOptions="StartAndExpand"
                HorizontalOptions="StartAndExpand"
                x:Name="ItemsList" IsVisible="False" SelectionMode="Single" 
                SelectionChanged="ItemsList_SelectionChanged">

                <CollectionView.ItemsLayout>
                    <GridItemsLayout x:Name="ItemsListItemsLayout" Span="{x:OnIdiom Tablet=3, Phone=2}" Orientation="Vertical" HorizontalItemSpacing="10" VerticalItemSpacing="10" />
                </CollectionView.ItemsLayout>

                <!--PAGINATION-->
                <CollectionView.Header>
                    <Label 
                        x:Name="ShowingTitle" Margin="5,10" TextColor="{DynamicResource LightGrayColor}"
                        FontSize="{StaticResource Medium}" HorizontalOptions="EndAndExpand"
                        VerticalOptions="CenterAndExpand" HorizontalTextAlignment="End" />
                </CollectionView.Header>

                <CollectionView.Footer>
                    <StackLayout Orientation="Horizontal" HorizontalOptions="FillAndExpand" Margin="0,10">
                        <Frame
                            x:Name="PreviousPageFrame" IsVisible="False"
                            Padding="5,5,10,5" Margin="0"
                            HorizontalOptions="StartAndExpand" VerticalOptions="CenterAndExpand"
                            Style="{DynamicResource ButtonFrameStyle}">
                            <Frame.GestureRecognizers>
                                <TapGestureRecognizer Tapped="PreviousPage_Tapped" />
                            </Frame.GestureRecognizers>
                            <StackLayout Orientation="Horizontal">
                                <Image
                                Aspect="AspectFit" HorizontalOptions="EndAndExpand" Margin="0">
                                    <Image.Source>
                                        <FontImageSource
                                        FontFamily="{DynamicResource MaterialFontFamily}"
                                        Glyph="{x:Static font:FontAwesomeIcons.ThinLeft}" />
                                    </Image.Source>
                                </Image>
                                <Label                                    
                                    FontSize="{StaticResource Small}"
                                    Style="{DynamicResource ButtonLabelStyle}"
                                    Text="{languages:Translate Previous}" Margin="-10,0,0,0"
                                    TextColor="{DynamicResource SameThemeColor}" />
                            </StackLayout>
                        </Frame>

                        <Label 
                            x:Name="PageNumber" HorizontalTextAlignment="Center"
                            FontSize="{StaticResource Medium}" TextColor="{DynamicResource DarkGrayColor}"
                            VerticalOptions="CenterAndExpand" HorizontalOptions="CenterAndExpand" />

                        <Frame
                            x:Name="NextPageFrame" IsVisible="False"
                            Padding="10,5,5,5" Margin="0"
                            HorizontalOptions="EndAndExpand" VerticalOptions="CenterAndExpand"
                            Style="{DynamicResource ButtonFrameStyle}">
                            <Frame.GestureRecognizers>
                                <TapGestureRecognizer Tapped="NextPage_Tapped" />
                            </Frame.GestureRecognizers>
                            <StackLayout Orientation="Horizontal">
                                <Label
                                FontSize="{StaticResource Small}"
                                Style="{DynamicResource ButtonLabelStyle}"
                                Text="{languages:Translate Next}" Margin="0,0,-10,0" />
                                <Image
                                Aspect="AspectFit" HorizontalOptions="EndAndExpand" Margin="0">
                                    <Image.Source>
                                        <FontImageSource
                                        FontFamily="{DynamicResource MaterialFontFamily}"
                                        Glyph="{x:Static font:FontAwesomeIcons.ThinRight}"
                                        Color="{DynamicResource SameThemeColor}" />
                                    </Image.Source>
                                </Image>
                            </StackLayout>
                        </Frame>
                    </StackLayout>
                </CollectionView.Footer>
                <!--PAGINATION-->

                <CollectionView.ItemTemplate>
                    <DataTemplate>
                         <Frame
                            Margin="5" x:Name="productViewCake"
                            Padding="5" BackgroundColor="{DynamicResource SameThemeColor}"
                            CornerRadius="10" HasShadow="False" HorizontalOptions="StartAndExpand"
                            VerticalOptions="StartAndExpand">
                            <StackLayout>
                                <Image
                                    Aspect="AspectFit"
                                    HeightRequest="120"
                                    Source="{Binding ItemID, Converter={StaticResource ImagePathConverter}, ConverterParameter='Item'}" />
                                <Label
                                    FontFamily="{DynamicResource OpenSansSemiBold}" FontSize="{StaticResource Small}"
                                    Text="{Binding ItemName}" LineBreakMode="TailTruncation"
                                    Margin="0" Padding="0"
                                    TextColor="{DynamicResource DarkGrayColor}"
                                    VerticalOptions="CenterAndExpand" />
                                <Label
                                    FontFamily="{DynamicResource OpenSansLight}"
                                    FontSize="{StaticResource Small}"
                                    HorizontalOptions="Start" Margin="0" Padding="0"
                                    Text="{Binding ItemCategory.ItemCategoryName}" LineBreakMode="TailTruncation"
                                    TextColor="{DynamicResource LightGrayColor}"
                                    VerticalOptions="CenterAndExpand" />

                                <Label
                                    FontFamily="{DynamicResource OpenSansBold}"
                                    FontSize="{StaticResource Normal}"
                                    HorizontalOptions="Start"                
                                    Text="{Binding CurrentPrice}"
                                    TextColor="{DynamicResource AppThemeColor}"
                                    VerticalOptions="CenterAndExpand" />
                            </StackLayout>
                        </Frame>
                    </DataTemplate>
                </CollectionView.ItemTemplate>
            </CollectionView>

        </StackLayout>
    </ScrollView>
  

Мой XAML.cs:

 internal async Task BindItems()
{
    var jsonResponse = await WebApiService.ProcessRequestAsync(JsonMethods.GetItems);

    var data = (JObject)JsonConvert.DeserializeObject(jsonResponse.ResponseJson);
    int totalItems = data["TotalCount"].Value<int>();
    var list = data["ItemMasters"].Value<JToken>().ToObject<List<ItemMaster>>();

    ItemsList.RemoveBinding(ItemsView.ItemsSourceProperty);
    //ItemsList.ItemsSource = null;

    if (list.Count > 0)
    {
        ItemsList.SetBinding(ItemsView.ItemsSourceProperty, new Binding("list"));
        //ItemsList.ItemsSource = list;
        ItemsList.IsVisible = true;
        NoItemLabel.IsVisible = false;

        int widthPerElement = 170;
        int span = (Application.Current.MainPage.Width / widthPerElement).ToProperInt();
        ItemsListItemsLayout.Span = span;

        totalPages = (totalItems / takeCount)   1;
        currentPage = (currentStartingCount / takeCount)   1;

        int showingTo = currentStartingCount   takeCount;
        if (showingTo > totalItems) showingTo = totalItems;

        ShowingTitle.Text = string.Format(TranslateExtension.Translate("ShowingTitle"), currentStartingCount   1, showingTo, totalItems, TranslateExtension.Translate("Products").ToLowerInvariant());
        PageNumber.Text = string.Format(TranslateExtension.Translate("PageNumber"), currentPage, totalPages);

        //previous frame
        if (currentPage <= 1 || totalPages <= 1)
        {
            PreviousPageFrame.IsVisible = false;
        }
        else
        {
            PreviousPageFrame.IsVisible = true;
        }

        //next frame
        if (currentPage >= totalPages || totalPages <= 1)
        {
            NextPageFrame.IsVisible = false;
        }
        else
        {
            NextPageFrame.IsVisible = true;
        }

    }
    else
    {
        ItemsList.IsVisible = false;
        NoItemLabel.IsVisible = true;
    }

}
  

Комментарии:

1. Вы тестируете с последней версией Xamarin.forms?

2. @JackHua-MSFT Да.Visual Studio: 16.7.1 Xamarin: 16.7.000.440 Xamarin iOS: 13.20.2.2

3. Я просто пишу демо-версию и обновляю ItemsLayout.span в коде позади не приведет к сбою. Я бы рекомендовал вам привязать эти свойства ItemsSource / isVisible вместо того, чтобы устанавливать их в коде позади.

4. Вы нашли решение для этой проблемы? @new_geek