C# 如果不隐藏/变形现有项,则无法将元素添加到Xamarin Forms iOS上的CollectionView
下面是一个示例应用程序,它说明了我的问题(完整源代码为:) 它在UWP和Android上运行良好,但在iOS上,如果单击“添加标签”或“添加条目”按钮,预加载的20项列表将消失(或缩小到0高度)。添加更多控件仍然只显示最后一个控件,向下移动页面。偶尔,先前添加的控件之一会随机出现 基本上只是想知道我是做错了什么,还是这是一个bug MainPage.xamlC# 如果不隐藏/变形现有项,则无法将元素添加到Xamarin Forms iOS上的CollectionView,c#,ios,xamarin,xamarin.forms,xamarin.ios,C#,Ios,Xamarin,Xamarin.forms,Xamarin.ios,下面是一个示例应用程序,它说明了我的问题(完整源代码为:) 它在UWP和Android上运行良好,但在iOS上,如果单击“添加标签”或“添加条目”按钮,预加载的20项列表将消失(或缩小到0高度)。添加更多控件仍然只显示最后一个控件,向下移动页面。偶尔,先前添加的控件之一会随机出现 基本上只是想知道我是做错了什么,还是这是一个bug MainPage.xaml <StackLayout> <Button Text="Add Label" Clicked
<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}"});
}
}
}
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 });
}
}
使用System.Collections.ObjectModel;
使用系统组件模型;
使用Xamarin.Forms;
命名空间集合视图示例
{
[设计时间可见(错误)]
公共部分类主页:ContentPage
{
公共主页()
{
初始化组件();
MyCollectionView.BindingContext=this;
MyCollectionView.SetBinding(ItemsView.ItemsSourceProperty,名称为(控制器));
//一次添加这20个项目就可以了
对于(变量x=0;x<20;x++)
{
Add(在{ControlList.Count}添加的新标签{Text=$”;
}
}
公共ObservableCollection控制器{get;set;}=new ObservableCollection();
已单击私有无效按钮1(对象发送方,事件参数e)
{
//将单个控件添加到ControlList会弄乱以前的控件的显示
//在iOS上添加项目
Add(在{ControlList.Count}添加的新标签{Text=$”;
}
已单击私有无效按钮2(对象发送方,事件参数e)
{
//将单个控件添加到ControlList会弄乱以前的控件的显示
//在iOS上添加项目
Add(在{ControlList.Count}处添加的新条目{Text=$”;
}
}
}
下面是一个简单的示例:
创建一个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>
在您的page.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}"});
}
}
}
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 });
}
}
public分部类主页面:ContentPage
{
公共主页()
{
初始化组件();
MyCollectionView.BindingContext=this;
MyCollectionView.SetBinding(ItemsView.ItemsSourceProperty,名称为(控制器));
//一次添加这20个项目就可以了
对于(变量x=0;x<20;x++)
{
Add(在{ControlList.Count}添加的新CollectionData{Name=$”,类型=1});
}
}
公共ObservableCollection控制器{get;set;}=new ObservableCollection();
已单击私有无效按钮1(对象发送方,事件参数e)
{
//将单个控件添加到ControlList会弄乱以前的控件的显示
//在iOS上添加项目
Add(在{ControlList.Count}添加的新CollectionData{Name=$”,类型=1});
}
已单击私有无效按钮2(对象发送方,事件参数e)
{
//将单个控件添加到ControlList会弄乱以前的控件的显示
//在iOS上添加项目
Add(在{ControlList.Count}添加的新CollectionData{Name=$”,类型=2});
}
}
我建议您使用而不是将ItemSource设置为View,这可能适用于示例,但我的实际应用程序要复杂得多,其中,从ObservableCollection呈现的每个控件都是一个在网格内组成的复合控件,包含自己的绑定和自定义控件。你是说这是唯一的解决方法吗?这项技术在StackLayout和TableView中工作得很好,但它们在我们尝试做的事情上都有各自的问题。StackLayout需要管理哪些元素具有焦点和可见性,而TableView的高度有问题(可能需要单独的问题)。这项技术在UWP和Android上运行良好,但iOS似乎有问题。答案信息丰富,但不是我想要的解决方案。您可以在datatemplate中定义复合控件,而不仅仅是上面的一个条目或标签。