Xamarin表单集合视图ItemsSource绑定未更新UI

时间:2019-05-29 11:36:32

标签: xamarin xamarin.forms collectionview itemssource

如果我在后面的代码中设置了绑定,则Xamarin.Forms 4.0集合视图ItemsSource绑定将无法正常工作。这些项目是基于源集合的初始值显示的,但是,在更新源集合时,UI不会更新。如果在xaml中设置绑定,则同样有效。

后面的代码:

    public MainPage()
    {
        this.InitializeComponent();
        this.BindingContext = this.mainViewModel = new MainViewModel();


        CollectionView courseCollectionView = new CollectionView
        {
            ItemSizingStrategy = ItemSizingStrategy.MeasureFirstItem,
            ItemTemplate = new DataTemplate(typeof(ItemView))
        };


     courseCollectionView.SetBinding(CollectionView.ItemsSourceProperty, 
     new Binding() { Source = this.mainViewModel.CountryNames, Mode = 
     BindingMode.TwoWay });

     courseCollectionView.ItemsLayout = new GridItemsLayout(4, 
      ItemsLayoutOrientation.Vertical);

        this.CoursesStack.Children.Clear();
        this.CoursesStack.Children.Add(courseCollectionView);

    }

查看用于ItemSource绑定的模型属性:

   ObservableCollection<Country> countryNames;

    public ObservableCollection<Country> CountryNames
    {
        get => this.countryNames;
        set
        {
            this.countryNames = value;
            RaisePropertyChanged("CountryNames");
        }
    }

预期:应根据对绑定到ItemsSource属性的ObsevableCollection(从集合中添加/删除项目)所做的更改来更新视图。

实际:视图不会随着ObservableCollection的更改而更新。

3 个答案:

答案 0 :(得分:1)

我相信您的绑定是错误的。尝试: courseCollectionView.SetBinding(CollectionView.ItemsSourceProperty, nameof(mainViewModel.CountryNames));

您需要指定PathmainViewModel.CountryNames)而不是Source

答案 1 :(得分:0)

在这种情况下,请尝试从 INotifyPropertyChanged 扩展主页,而不是在set属性中使用 RaisePropertyChanged(“ CountryNames”),而是使用 OnPropertyChanged() >

答案 2 :(得分:0)

关于使用CollectionView时更新UI,我做了一个示例,您可以看一下:

public partial class MainPage : ContentPage
{
    public mainvidemodel viewmodel { get; set; }
    public MainPage()
    {
        InitializeComponent();
        viewmodel = new mainvidemodel();
        this.BindingContext = viewmodel;

        CollectionView collectionView = new CollectionView();

        collectionView.SetBinding(ItemsView.ItemsSourceProperty, "countries");

        collectionView.ItemTemplate = new DataTemplate(() =>
        {
            StackLayout stacklayout = new StackLayout();

            Label label1 = new Label();
            label1.SetBinding(Label.TextProperty,"Id");

            Label label2 = new Label();
            label2.SetBinding(Label.TextProperty, "Name");

            Label label3 = new Label();
            label3.SetBinding(Label.TextProperty, "caption");


            stacklayout.Children.Add(label1);
            stacklayout.Children.Add(label2);

            stacklayout.Children.Add(label3);
            return stacklayout;

        });
        Button btn = new Button() { Text = "btn", WidthRequest = 200, HeightRequest = 50 };
        btn.Clicked += Btn_Clicked;
        stacklayout1.Children.Add(collectionView);
        stacklayout1.Children.Add(btn);

    }

    private void Btn_Clicked(object sender, EventArgs e)
    {
        viewmodel.countries.Add(new Country()  { Id = 8, Name = "country8", caption = "caption 8" });
    }
}
public class mainvidemodel
{
    public ObservableCollection<Country> countries { get; set; }
    public mainvidemodel()
    {
        countries = new ObservableCollection<Country>()
        {
            new Country(){Id=1,Name="country1",caption="caption 1"},
            new Country(){Id=2,Name="country2",caption="caption 2"},
            new Country(){Id=3,Name="country3",caption="caption 3"},
            new Country(){Id=4,Name="country4",caption="caption 4"},
            new Country(){Id=5,Name="country5",caption="caption 5"},
            new Country(){Id=6,Name="country6",caption="caption 6"},
            new Country(){Id=7,Name="country7",caption="caption 7"},

        };

    }
}
public class Country
{
    public int Id { get; set; }
    public string Name { get; set; }
    public string caption { get; set; }
}

enter image description here