在Xamarin Forms中将x:DataType设置为ViewModel时,CollectionView项不更新



我有一个CollectionView,它的ItemsSource绑定到ObservableCollection,它工作正常。但是,当我在XAML中添加x:DataType="viewmodels:MyPageViewModel"时,它不会显示任何项,即使是在ViewModel的构造函数中初始化的项也不会显示在CollectionView中。它也不显示更新的项目。

这是我的XAML代码(MyPage.XAML(:

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage ...
xmlns:viewmodels="clr-namespace:MyProject.ViewModels"
x:DataType="viewmodels:MyPageViewModel"
x:Class="MyProject.Views.MyPage">
<ContentPage.Content>
<StackLayout>
<CollectionView ItemsSource="{Binding Strings}">
<CollectionView.ItemTemplate>
<DataTemplate>
<StackLayout>
<Label Text="{Binding .}" />
</StackLayout>
</DataTemplate>
</CollectionView.ItemTemplate>
</CollectionView>
<Button Text="Add More" Command="{Binding AddMoreItemsCommand}" />
</StackLayout>
</ContentPage.Content>
</ContentPage>

这里我在C#代码隐藏(MyPage.xaml.cs(中指定了绑定:

BindingContext = new ViewModels.MyPageViewModel();

这是我的ViewModel(MyPageViewModel.cs(:

public class MyPageViewModel : INotifyPropertyChanged
{
public ObservableCollection<string> Strings { get { return strings; } set { strings = value; OnPropertyChanged(nameof(Strings)); } }
ObservableCollection<string> strings;
public MyPageViewModel()
{
Strings = new ObservableCollection<string> { "1", "2", "3" };
}
public ICommand AddMoreItemsCommand => new Command(() =>
{
Strings.Add("4");
Strings.Add("5");
Strings.Add("6");
});
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged(string propertyName)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}

请注意,如果我删除x:DataType="viewmodels:MyPageViewModel",一切都会正常工作。此外,如果我在应用程序运行时编辑ColllectionView中的某些内容,它会通过XAML热重新加载按预期正确地渲染项目。但它不能满足需求,因为如果我再次运行该项目,它就不起作用。

Xamarin Forms中有漏洞吗?我正在运行最新的Xamarin.Forms 5.0.0.2515,我也在Xamarin.Form 5.0.0.2478中尝试过它?还是我错过了什么?任何帮助都将不胜感激。

CollectionView<DataTemplate>中指定x:DataType="modelOfYourCollection"

如果您使用的任何控件都有DataTemplate,则还必须在其上设置已编译的绑定。这里,我们有一个CollectionView,它是绑定到ObservableCollection<string>的数据。我们可以引入System命名空间,就像我们为viewmodels:MyPageViewModel所做的那样,因为我们使用的是字符串类型的集合,并且string类驻留在System命名空间中。

  • 首先,在页面的根目录中添加名称空间:
xmlns:sys="clr-namespace:System;assembly=System.Runtime"
  • 然后在DataTemplate中添加:
<DataTemplate x:DataType="sys:String">

如果我们使用自己的自定义模型,请在页面的根位置添加模型的命名空间,然后在CollectionViewDataTemplate中指定模型类注意我们必须在DataTemplate中使用Model而不是ViewModel。

其余代码是正确的

最终XAML代码看起来像:

<ContentPage ...
xmlns:viewmodels="clr-namespace:MyProject.ViewModels"
xmlns:models="clr-namespace:MyProject.Models"
xmlns:sys="clr-namespace:System;assembly=System.Runtime"
x:DataType="viewmodels:MyPageViewModel"
x:Class="MyProject.Views.MyPage">
...
<CollectionView ItemsSource="{Binding Strings}">
<CollectionView.ItemTemplate>
<DataTemplate x:DataType="sys:String">
<Label Text="{Binding .}" />
</DataTemplate>
</CollectionView.ItemTemplate>
</CollectionView>
<!-- For collection of your custom model -->
<CollectionView ItemsSource="{Binding Monkeys}" >
<CollectionView.ItemTemplate>
<DataTemplate x:DataType="models:MonkeyModel">
<Label Text="{Binding MonkeyName}" />
</DataTemplate>
</CollectionView.ItemTemplate>
</CollectionView>
</ContentPage>

为什么使用编译绑定编译绑定的解析速度比经典绑定快。因此,提高了Xamarin.Forms应用程序中的数据绑定性能

  • 有关更多详细信息,请参阅James Montemagno的博客。

  • 请参阅此处获取Xamarin.Forms Compiled Bindings官方文档。

相关内容

  • 没有找到相关文章

最新更新