Android ListView在元素添加到绑定的ObservableCollection(Xamarin)后未更新

Android ListView在元素添加到绑定的ObservableCollection(Xamarin)后未更新,android,listview,xamarin,observablecollection,Android,Listview,Xamarin,Observablecollection,我在StackOverflow上发现了许多类似的问题,但似乎无法解决这个问题 我正在尝试将ObservableCollection绑定到ListView,以便当集合的内容更改时,ListView将自动更新。不幸的是,当元素被添加到集合中时(通过单击按钮),ListView没有被更新。如何使ListView反映集合的当前内容 注意:如果我使用listView.RequestLayout()强制布局,那么列表视图将包含正确数量的项目。但是,它不一定包含正确的项目。例如,如果删除第一个项目并在末尾添加

我在StackOverflow上发现了许多类似的问题,但似乎无法解决这个问题

我正在尝试将ObservableCollection绑定到ListView,以便当集合的内容更改时,ListView将自动更新。不幸的是,当元素被添加到集合中时(通过单击按钮),ListView没有被更新。如何使ListView反映集合的当前内容

注意:如果我使用
listView.RequestLayout()强制布局,那么列表视图将包含正确数量的项目。但是,它不一定包含正确的项目。例如,如果删除第一个项目并在末尾添加一个新项目,则强制布局没有效果。如果我在删除第一项后强制布局,然后在末尾添加一项后再次强制布局,则内容是正确的

活动代码

public class MainActivity : Activity
{
    int count = 1;

    protected override void OnCreate(Bundle bundle)
    {
        base.OnCreate(bundle);

        ObservableCollection<UserTask> allTasksCollection = new ObservableCollection<UserTask>();
        while(count < 6)
        {
            allTasksCollection.Add(new UserTask("Task number " + count));
            count++;
        }

        // Set our view from the "main" layout resource
        SetContentView(Resource.Layout.Main);

        // Bind listview to all tasks
        ListView listView = FindViewById<ListView>(Resource.Id.allTasksListView);
        UserTaskListAdapter adapter = new UserTaskListAdapter(this, allTasksCollection);
        listView.Adapter = adapter;

        // Button click should add a new task and remove the first task. 
        Button button = FindViewById<Button>(Resource.Id.myButton);
        button.Click += delegate {                
            allTasksCollection.Add(new UserTask("Task number " + count));
            button.Text = string.Format("{0} tasks!", count++);
        };
    }
}
公共类main活动:活动
{
整数计数=1;
创建时受保护的覆盖无效(捆绑包)
{
base.OnCreate(bundle);
ObservableCollection allTasksCollection=新的ObservableCollection();
而(计数<6)
{
添加(新用户任务(“任务编号”+count));
计数++;
}
//从“主”布局资源设置视图
SetContentView(Resource.Layout.Main);
//将listview绑定到所有任务
ListView ListView=FindViewById(Resource.Id.allTasksListView);
UserTaskListAdapter=新的UserTaskListAdapter(此,allTasksCollection);
Adapter=适配器;
//单击按钮应添加新任务并删除第一个任务。
Button Button=FindViewById(Resource.Id.myButton);
按钮。单击+=委托{
添加(新用户任务(“任务编号”+count));
button.Text=string.Format(“{0}任务!”,count++);
};
}
}
适配器

public class UserTaskListAdapter : BaseAdapter<UserTask>
{
    Activity context;
    ObservableCollection<UserTask> list;

    public UserTaskListAdapter(Activity _context, ObservableCollection<UserTask> _list)
    : base()
    {
        this.context = _context;
        this.list = _list;
    }

    public override int Count
    {
        get { return list.Count; }
    }

    public override long GetItemId(int position)
    {
        return position;
    }

    public override UserTask this[int index]
    {
        get { return list[index]; }
    }

    public override View GetView(int position, View convertView, ViewGroup parent)
    {
        View view = convertView;
        if (view == null)
            view = context.LayoutInflater.Inflate(Resource.Layout.UserTaskRowItem, parent, false);

        UserTask item = this[position];
        view.FindViewById<TextView>(Resource.Id.Title).Text = item.Name;

        return view;
    }
}
公共类UserTaskListAdapter:BaseAdapter { 活动语境; 可观察收集清单; public UserTaskListAdapter(活动_上下文,ObservableCollection _列表) :base() { this.context=\u context; this.list=\u list; } 公共覆盖整数计数 { 获取{return list.Count;} } 公共覆盖长GetItemId(int位置) { 返回位置; } public override UserTask this[int index] { 获取{返回列表[索引];} } 公共覆盖视图GetView(int位置、视图转换视图、视图组父视图) { 视图=转换视图; 如果(视图==null) 视图=context.LayoutInflater.Inflate(Resource.Layout.UserTaskRowItem,父项,false); UserTask item=此[职位]; view.findviewbyd(Resource.Id.Title).Text=item.Name; 返回视图; } }
主XAML

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:id="@+id/rootLayout">
        <LinearLayout
            android:orientation="vertical"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:id="@+id/allTasksContainer">
            <Button
                android:id="@+id/myButton"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:text="@string/hello" />
            <ListView
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:id="@+id/allTasksListView" />
        </LinearLayout>
</LinearLayout>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content">
    <LinearLayout
        android:orientation="horizontal"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/linearLayoutHorizontal">
        <LinearLayout
            android:orientation="vertical"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:id="@+id/CheckboxContainer">
            <CheckBox
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:id="@+id/checkboxSelect" />
        </LinearLayout>
        <LinearLayout
            android:orientation="vertical"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:id="@+id/TextContainer">
            <TextView
                android:text="Large Text"
                android:textAppearance="?android:attr/textAppearanceLarge"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:id="@+id/Title" />
            <TextView
                android:text="Small Text"
                android:textAppearance="?android:attr/textAppearanceSmall"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:id="@+id/DueDate" />
        </LinearLayout>
    </LinearLayout>
</RelativeLayout>

列表项XAML

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:id="@+id/rootLayout">
        <LinearLayout
            android:orientation="vertical"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:id="@+id/allTasksContainer">
            <Button
                android:id="@+id/myButton"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:text="@string/hello" />
            <ListView
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:id="@+id/allTasksListView" />
        </LinearLayout>
</LinearLayout>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content">
    <LinearLayout
        android:orientation="horizontal"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/linearLayoutHorizontal">
        <LinearLayout
            android:orientation="vertical"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:id="@+id/CheckboxContainer">
            <CheckBox
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:id="@+id/checkboxSelect" />
        </LinearLayout>
        <LinearLayout
            android:orientation="vertical"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:id="@+id/TextContainer">
            <TextView
                android:text="Large Text"
                android:textAppearance="?android:attr/textAppearanceLarge"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:id="@+id/Title" />
            <TextView
                android:text="Small Text"
                android:textAppearance="?android:attr/textAppearanceSmall"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:id="@+id/DueDate" />
        </LinearLayout>
    </LinearLayout>
</RelativeLayout>

看看INotifyPropertyChanged接口。它将警告listview,listview中的对象中的变量已更改


编辑:误读你的问题。我的错。

尝试在适配器上调用NotifyDataSetChanged(),更新其项目后,Android中的AFAIK ListView不会观察到您的ObservableCollection上的更改:

请尝试以下代码:

    button.Click += delegate {                
        allTasksCollection.Add(new UserTask("Task number " + count));
        button.Text = string.Format("{0} tasks!", count++);
        adapter.NotifyDataSetChanged();
    };
您还可以尝试将litener添加到ObservableCollection,在适配器中,将构造函数更改为:

this.list.CollectionChanged += (sender,args) => { NotifyDataSetChanged(); };

是的,我认为集合中的对象最终必须实现INotifyPropertyChanged。但是,这对于从集合中添加/删除内容并不重要。。据我所知,ObservableCollection应该处理这个问题。@pulekies这是正确的。listview应该可以看到它们。稍后我会再看一遍,也许我能帮上忙。非常感谢@Hichaam!您提供的两种解决方案都提供了我想要的结果。我认为第二个可能是更好的解决方案,我会用它。很高兴它有帮助。