INotifyPropertyChanged-如果UI字段更改,则可观察的集合不会回发

问题描述

我一直在查看INotifyPropertyChanged()的许多示例。

我找到了以下示例:

https://xamarindev.co.uk/mvvm-and-xamarin-forms/

我已经用它创建了一个测试项目,并且一切正常……使用断点,例如

public int Age
{
    get { return _person.Age; }
    set
    {
        _person.Age = value;
        OnPropertyChanged("Age");
        OnPropertyChanged("UserInfo");
    }
}
用户在应用程序上更改年龄时,会点击

此问题唯一的麻烦是,我需要多个人员,而不是Person的一个实例,因此我添加一个ObservableCollection,使其看起来像:

    public class viewmodel1 : BaseModel
{
    private ObservableCollection<Person> _Persons;
    public ObservableCollection<Person> Persons
    {
        get { return _Persons; }
        set
        {
            if (_Persons == value) return;
            _Persons = value;
        }
    }

    private Person _person;
    public viewmodel1()
    {
        Persons = new ObservableCollection<Person>();

        //// set some default here for example
        _person = new Person
        {
            Age = 21,FirstName = "Steve",LastName = "Hawkins"
        };
        Persons.Add(_person);

        _person = new Person
        {
            Age = 19,FirstName = "JimBob",LastName = "Jones"
        };
        Persons.Add(_person);
    }

    public int Age
    {
        get { return _person.Age; }
        set
        {
            _person.Age = value;
            OnPropertyChanged("Age");
            OnPropertyChanged("UserInfo");
        }
    }

    public string FirstName
    {
        get { return _person.FirstName; }
        set
        {
            _person.FirstName = value;
            OnPropertyChanged("FirstName");
            OnPropertyChanged("UserInfo");
        }
    }

    public string LastName
    {
        get { return _person.LastName; }
        set
        {
            _person.LastName = value;
            OnPropertyChanged("LastName");
            OnPropertyChanged("UserInfo");
        }
    }

    public string UserInfo
    {
        get
        {
            // return _person.PersonInfo();
            return _Persons[0].PersonInfo();
        }
    }
}

,然后将视图更改为显示ListView:

 <ContentPage.Content>
        <StackLayout>
                      <ListView  x:Name="producttablelist" IsVisible="True" VerticalOptions="FillAndExpand" HasUnevenRows="True" ItemsSource="{Binding Persons}" HeightRequest="1500">
                <ListView.ItemTemplate>
                    <DataTemplate>
                        <ViewCell>
                            <StackLayout HeightRequest="120" BackgroundColor="Green" HorizontalOptions="StartAndExpand">
                                <Grid>
                                    <Grid.RowDeFinitions>
                                        <RowDeFinition Height="Auto"/>
                                        <RowDeFinition Height="Auto"/>
                                    </Grid.RowDeFinitions>
                                    <Grid.ColumnDeFinitions>
                                        <ColumnDeFinition Width="Auto"/>
                                        <ColumnDeFinition Width="*"/>
                                    </Grid.ColumnDeFinitions>
                                    <Editor Grid.Row="1" Grid.Column="1" Text="{Binding FirstName,Mode=TwoWay}" HorizontalOptions="CenterandExpand" TextColor="Black" />
                                    <Editor Grid.Row="1" Grid.Column="2" Text="{Binding LastName,Mode=TwoWay}" HorizontalOptions="CenterandExpand" TextColor="Black" />
                                    <Editor Grid.Row="2" Grid.Column="1" Text="{Binding Age,Mode=TwoWay}" HorizontalOptions="CenterandExpand" TextColor="Black" />
                                    <Label Grid.Row="2" Grid.Column="2" Text="{Binding UserInfo}" HorizontalOptions="StartAndExpand" TextColor="Black" />
                                </Grid>
                            </StackLayout>
                        </ViewCell>
                    </DataTemplate>
                </ListView.ItemTemplate>
            </ListView>

        </StackLayout>
    </ContentPage.Content>
</ContentPage>

现在,该页面加载时显示了2位用户,但是如果用户更改了应用程序上的年龄...什么都没有发生..它不会在VM中回发到年龄...

有人可以帮忙吗?

看看在https://riptutorial.com/xaml/example/28804/binding-to-a-collection-of-objects-with-inotifypropertychanged-and-inotifycollectionchanged上找到的其他示例

https://stackoverflow.com/questions/32667408/how-to-implement-inotifypropertychanged-in-xamarin-forms

如果我使用ObservableCollection,似乎仍然无法解决问题,并且随着年龄的变化,我还需要添加其他逻辑,因此我希望通过VM而不是Person类来完成此操作(我发现的一些示例已经显示

TY寻求帮助

解决方法

正如杰森所说:the "Age" entry is bound to the Age property of each person object in your data,not to the Age property of the base VM

您不需要在ViewModel中编写这些属性,因为这些属性存在于Person模型中。

您真正想要绑定的是Text="{Binding Person.FirstName,Mode=TwoWay}"而不是ViewModel1.FirstName

您可以在此处编写Text="{Binding FirstName,Mode=TwoWay}",因为数据绑定将搜索根属性,直到在模型FirstName中找到属性Person

引用:data-bindings-to-mvvm

,

也许尝试使用SetProperty,它继承自INotifyPropertyChanged,即像下面的代码那样编写您的公共属性:

    private ObservableCollection<Person> _persons;

    public ObservableCollection<Person> Persons
    {
        get => _persons;
        set => SetProperty(ref _persons,value);
    }

ps ....如果遇到问题,您的baseModel可能也需要继承自INotifyPropertyChanged。我还假设您正在使用像PrismMVVM这样的MVVM框架

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...