Xamarin表单集合视图项资源绑定未更新UI

Xamarin表单集合视图项资源绑定未更新UI,xamarin,xamarin.forms,collectionview,itemssource,Xamarin,Xamarin.forms,Collectionview,Itemssource,如果我在代码隐藏中设置绑定,则Xamarin.Forms 4.0集合视图项资源绑定将无法按预期工作。这些项是基于源集合的初始值显示的,但更新源集合时UI不会更新。如果我在xaml中设置绑定,同样可以工作 代码隐藏: 查看用于ItemsSource绑定的模型属性: ObservableCollection<Country> countryNames; public ObservableCollection<Country> CountryNames

如果我在代码隐藏中设置绑定,则Xamarin.Forms 4.0集合视图项资源绑定将无法按预期工作。这些项是基于源集合的初始值显示的,但更新源集合时UI不会更新。如果我在xaml中设置绑定,同样可以工作

代码隐藏:
查看用于ItemsSource绑定的模型属性:

   ObservableCollection<Country> countryNames;

    public ObservableCollection<Country> CountryNames
    {
        get => this.countryNames;
        set
        {
            this.countryNames = value;
            RaisePropertyChanged("CountryNames");
        }
    }
observedcollection国家名称;
公共可观察收集国家名称
{
get=>this.countryNames;
设置
{
this.countryNames=值;
RaiseProperty变更(“国家名称”);
}
}
预期:视图应根据对绑定到ItemsSource属性的ObsevableCollection(从集合中添加/删除项)所做的更改进行更新


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

在这种情况下,请尝试从INotifyPropertyChanged扩展主页面,而不是在set属性中使用OnPropertyChanged()我相信您的绑定是错误的。尝试:
courseCollectionView.SetBinding(CollectionView.ItemsSourceProperty,nameof(mainViewModel.CountryNames))


关于使用CollectionView时更新UI,您需要指定
路径(
mainViewModel.CountryNames
),而不是
源代码
,我做了一个示例,您可以查看一下:

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; }
}
public分部类主页面:ContentPage
{
public mainvidemodel视图模型{get;set;}
公共主页()
{
初始化组件();
viewmodel=新的mainvidemodel();
this.BindingContext=viewmodel;
CollectionView CollectionView=新建CollectionView();
collectionView.SetBinding(ItemsView.ItemsSourceProperty,“国家”);
collectionView.ItemTemplate=新数据模板(()=>
{
StackLayout StackLayout=新的StackLayout();
标签标签1=新标签();
label1.SetBinding(Label.TextProperty,“Id”);
Label label2=新标签();
label2.SetBinding(Label.TextProperty,“名称”);
标签标签3=新标签();
label3.SetBinding(Label.TextProperty,“标题”);
stacklayout.Children.Add(标签1);
stacklayout.Children.Add(标签2);
stacklayout.Children.Add(标签3);
返回堆栈布局;
});
按钮btn=新按钮(){Text=“btn”,宽度请求=200,高度请求=50};
点击次数+=点击次数;
stacklayout1.Children.Add(collectionView);
stacklayout1.Children.Add(btn);
}
私有无效Btn_已单击(对象发送方,事件参数e)
{
添加(newcountry(){Id=8,Name=“country8”,caption=“caption 8”});
}
}
公共类mainvidemodel
{
公共可观察收集国家{get;set;}
公共mainvidemodel()
{
国家/地区=新的可观测集合()
{
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”},
};
}
}
公营国家
{
公共int Id{get;set;}
公共字符串名称{get;set;}
公共字符串标题{get;set;}
}

当您说“不随更改更新”时,是指从收藏中添加/删除项目吗?或者您的意思是更改集合中单个项目的属性?当我从集合中添加/删除项目时,UI不会更新。您不需要在代码隐藏中绑定项目资源-您可以直接分配它。但这可能不是根本问题。您也不应该需要CollectionView的双向绑定是的,我可以在xaml中绑定它,但是,正如这里提到的,collection视图上有一个打开的bug/task。我需要在设备方向改变时更新ItemsLayout。不管怎样,@ottermatic解决方案对我有效。谢谢:)@Jason更改项目属性时如何?MainViewModel已经从INotifyPropertyChanged扩展而来,如果我在Xaml中设置binding if ItemsSource,它的工作状态很好。现在工作状态很好!谢谢。是的,我的装订错了。
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; }
}