在没有 hiding/deforming 个现有项目的情况下,无法将元素添加到 Xamarin Forms iOS 上的 CollectionView

Cannot add elements to a CollectionView on Xamarin Forms iOS without hiding/deforming existing items

这是一个示例应用程序,可以说明我的问题(完整源代码位于:https://github.com/cmpalmer66/CollectionViewSample

它在 UWP 和 Android 上工作正常,但在 iOS 上,如果您单击“添加标签”或“添加条目”按钮,预加载的 20 项列表将消失(或缩小到 0 高度) .添加更多控件仍然只显示最后一个,向下移动页面。有时,先前添加的控件之一会随机出现。

基本上只是想知道我是否做错了什么或者这是一个错误。

MainPage.xaml

<StackLayout>
    <Button Text="Add Label" Clicked="Button1_OnClicked" />
    <Button Text="Add Entry" Clicked="Button2_OnClicked" />

    <CollectionView x:Name="MyCollectionView">
        <CollectionView.ItemTemplate>
            <DataTemplate>
                <ContentView Content="{Binding .}"></ContentView>
            </DataTemplate>
        </CollectionView.ItemTemplate>
    </CollectionView>
</StackLayout>

MainPage.xaml.cs:

using System.Collections.ObjectModel;
using System.ComponentModel;
using Xamarin.Forms;

namespace CollectionViewSample
{
    [DesignTimeVisible(false)]
    public partial class MainPage : ContentPage
    {
        public MainPage()
        {
            InitializeComponent();
            MyCollectionView.BindingContext = this;
            MyCollectionView.SetBinding(ItemsView.ItemsSourceProperty, nameof(ControlList));
            // Adding these 20 items all at once works fine
            for (var x = 0; x < 20; x++)
            {
                ControlList.Add(new Label {Text = $"Added at {ControlList.Count}"});
            }
        }

        public ObservableCollection<View> ControlList { get; set; } = new ObservableCollection<View>();

        private void Button1_OnClicked(object sender, EventArgs e)
        {
            // Adding a single control to the ControlList will mess up the display of the previously
            // added items on iOS
            ControlList.Add(new Label {Text = $"Added at {ControlList.Count}"});
        }

        private void Button2_OnClicked(object sender, EventArgs e)
        {
            // Adding a single control to the ControlList will mess up the display of the previously
            // added items on iOS
            ControlList.Add(new Entry {Text = $"Added at {ControlList.Count}"});
        }
    }
}

下面是一个简单的示例:

创建一个 ViewTemplateSelector :

public class ViewTemplateSelector : DataTemplateSelector
{
    public DataTemplate LebelTemplate { get; set; }
    public DataTemplate EntryTemplate { get; set; }
    protected override DataTemplate OnSelectTemplate(object item, BindableObject container)
    {
        return ((CollectionData)item).Type == 1 ? LebelTemplate : EntryTemplate;
    }
}  

然后在您的页面中使用 xaml:

<ContentPage.Resources>
    <ResourceDictionary>
        <DataTemplate x:Key="labelTemplate">
        
                <Label Text="{Binding Name}"/>
  
        </DataTemplate>
        <DataTemplate x:Key="entryTemplate">

                <Entry Text="{Binding Name}"/>

        </DataTemplate>
        <local:ViewTemplateSelector x:Key="viewTemplateSelector"
            LebelTemplate="{StaticResource labelTemplate}"
            EntryTemplate="{StaticResource entryTemplate}" />
    </ResourceDictionary>
</ContentPage.Resources>
<ContentPage.Content>
    <StackLayout>
        <Button Text="Add Label" Clicked="Button1_Clicked" />
        <Button Text="Add Entry" Clicked="Button2_Clicked" />

        <CollectionView x:Name="MyCollectionView"  ItemTemplate="{StaticResource viewTemplateSelector}" >

        </CollectionView>
    </StackLayout>
</ContentPage.Content>

创建数据模式,添加一个Type决定使用哪个模板(这里1表示添加Label,2表示添加Entry):

public class CollectionData
{
    public string Name { get; set; }
    public int Type { get; set; }
}

在你的 page.xaml.cs:

public partial class MainPage : ContentPage
{
    public MainPage()
    {
        InitializeComponent();
        MyCollectionView.BindingContext = this;
        MyCollectionView.SetBinding(ItemsView.ItemsSourceProperty, nameof(ControlList));
        // Adding these 20 items all at once works fine
        for (var x = 0; x < 20; x++)
        {
             ControlList.Add(new CollectionData { Name = $"Added at {ControlList.Count}",Type = 1 });
        }
    }

    public ObservableCollection<CollectionData> ControlList { get; set; } = new ObservableCollection<CollectionData>();

    private void Button1_OnClicked(object sender, EventArgs e)
    {
        // Adding a single control to the ControlList will mess up the display of the previously
        // added items on iOS
         ControlList.Add(new CollectionData { Name = $"Added at {ControlList.Count}",Type = 1 });
    }

    private void Button2_OnClicked(object sender, EventArgs e)
    {
        // Adding a single control to the ControlList will mess up the display of the previously
        // added items on iOS
         ControlList.Add(new CollectionData { Name = $"Added at {ControlList.Count}",Type = 2 });
    }
}