【问题标题】:Xamarin Forms Collection view ItemsSource Binding not updating the UIXamarin 表单集合视图 ItemsSource 绑定未更新 UI
【发布时间】:2019-10-15 00:21:43
【问题描述】:

如果我在后面的代码中设置绑定,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);

    }

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

   ObservableCollection<Country> countryNames;

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

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

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

【问题讨论】:

  • 当您说“未更新更改”时,您的意思是从集合中添加/删除项目吗?或者您的意思是更改集合中各个项目的属性?
  • 当我从集合中添加/删除项目时,UI 没有更新。
  • 您不需要在后面的代码中绑定ItemsSource - 您可以直接分配它。但这可能不是根本问题。你也不应该需要一个 CollectionView 的双向绑定
  • 是的,我可以在 xaml 中绑定它,但是,这里提到的集合视图上有一个打开的错误/任务github.com/xamarin/Xamarin.Forms/issues/5354。而且我需要在设备方向更改时更新 ItemsLayout。无论如何@ottermatic 解决方案对我有用。谢谢你:)
  • @Jason 更改项目属性时怎么样?

标签: xamarin xamarin.forms collectionview itemssource


【解决方案1】:

关于在使用 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; }
}

【讨论】:

    【解决方案2】:

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

    您需要指定Path (mainViewModel.CountryNames) 而不是Source

    【讨论】:

    • 现在完美运行!非常感谢。是的,我的绑定错误。
    【解决方案3】:

    在这种情况下,尝试从 INotifyPropertyChanged 扩展 MainPage,而不是设置属性中的 RaisePropertyChanged("CountryNames"),使用 OnPropertyChanged()

    【讨论】:

    • MainViewModel 已经从 INotifyPropertyChanged 扩展而来,如果我在 Xaml 中设置了 ItemsSource 绑定,它的工作正常。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-07-03
    • 2015-03-07
    • 2018-06-26
    • 1970-01-01
    • 2022-01-06
    • 2022-10-18
    • 2020-06-29
    相关资源
    最近更新 更多