更新ListView的ObservableCollection中一项的显示 [英] Update display of one item in a ListView's ObservableCollection

查看:67
本文介绍了更新ListView的ObservableCollection中一项的显示的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个绑定到ObservableCollection的ListView.

I have a ListView which is bound to an ObservableCollection.

是否有一种方法可以在SomeModel项的属性发生更改时更新单个单元格,而无需通过更改ObservableCollection重新加载ListView?

Is there a way to update a single cell whenever a property of a SomeModel item changed, without reloading the ListView by changing the ObservableCollection?

(问题是从 https复制的://forums.xamarin.com/discussion/40084/update-item-properties-in-a-listviews-observablecollection ,就像我在那儿的答案一样.)

(Question is copied from https://forums.xamarin.com/discussion/40084/update-item-properties-in-a-listviews-observablecollection, as is my answer there.)

推荐答案

如我所见,您正在尝试将MVVM用作Xamarin.Forms应用程序的模式.您已经在使用ObservableCollection来显示数据列表.从集合中添加或删除新项目时,UI会相应刷新,这是因为ObserverbleCollection正在实现INotifyCollectionChanged.

As I can see you are trying to use MVVM as a pattern for your Xamarin.Forms app. You are already using the ObservableCollection for displaying a list of the data. When a new item is added or removed from collection UI will be refreshed accordingly and that is because the ObserverbleCollection is implementing INotifyCollectionChanged.

此问题想要实现的是下一个行为,当您想要更改集合中项的特定值并更新UI时,实现此问题的最佳和最简单方法是为模型实现INotifyPropertyChanged您收藏中的物品.

What you want to achieve with this question is next behaviour, when you want to change the particular value for the item in the collection and update the UI the best and simplest way to achieve that is to implement INotifyPropertyChanged for a model of the item from your collection.

伙计,我有一个简单的演示示例,说明了如何实现此目标,正如我所见,您的回答正在起作用,但我相信此示例对您来说会更好.

Bellow, I have a simple demo example on how to achieve that, your answer is working as I can see but I am sure this example would be nicer for you to use it.

我有带命令的简单Button和保存我的收集数据的ListView.

I have simple Button with command and ListView which holds my collection data.

这是我的页面,SimpleMvvmExamplePage.xaml:

<StackLayout>

    <Button Text="Set status" 
            Command="{Binding SetStatusCommand}" 
            Margin="6"/>

    <ListView ItemsSource="{Binding Cars}"
              HasUnevenRows="True">

        <ListView.ItemTemplate>
            <DataTemplate>
                <ViewCell>

                    <StackLayout Orientation="Vertical" 
                                 Margin="8">

                        <Label Text="{Binding Name}" 
                               FontAttributes="Bold" />

                        <StackLayout Orientation="Horizontal">

                            <Label Text="Seen?" 
                                   VerticalOptions="Center"/>

                            <CheckBox IsChecked="{Binding Seen}"
                                      Margin="8,0,0,0" 
                                      VerticalOptions="Center" 
                                      IsEnabled="False" />
                        </StackLayout>

                     </StackLayout>

                </ViewCell>
            </DataTemplate>
          </ListView.ItemTemplate>
     </ListView>

 </StackLayout>

此演示的基本思想是,当用户单击ListView上方的按钮时,更改属性Seen的值并为CheckBox设置值.

The basic idea from this demo is to change the value of the property Seen and set value for the CheckBox when the user clicks on that Button above the ListView.

这是我的Car.cs课.

public class Car : INotifyPropertyChanged
{
    private string name;
    public string Name
    {
        get { return name; }
        set 
        { 
            name = value;
            OnPropertyChanged();
        }
    }

    private bool seen;
    public bool Seen
    {
        get { return seen; }
        set 
        { 
            seen = value;
            OnPropertyChanged();
        }
    }

    // Make base class for this logic, something like BindableBase
    public event PropertyChangedEventHandler PropertyChanged;
    protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
}

在Github上的完整演示示例中,我使用我的BindableBase类,当在道具设置器中使用此SetProperty方法更改某些属性值时,我将在其中处理INotifyPropertyChanged的提升.

In the full demo example which is on my Github, I am using my BindableBase class where I handle raising the INotifyPropertyChanged when some property value is changed with this SetProperty method in the setter of the props.

您可以在此处找到实现: https://github.com/almirvuk/Theatrum/tree/master/Theatrum.Mobile/Theatrum.Mobile

You can find the implementation here: https://github.com/almirvuk/Theatrum/tree/master/Theatrum.Mobile/Theatrum.Mobile

最后要显示的是此页面的ViewModel,并且在ViewModel内,当用户单击集合中的项目时,我会将Seen属性的值更改为True. ListView上方的Button.这是我的SimpleMvvmExamplePageViewModel.cs

The last thing to show is my ViewModel for this page, and inside of the ViewModel, I will change the value of Seen property to True for items in the collection when the user clicks on the Button above the ListView. Here is my SimpleMvvmExamplePageViewModel.cs

public class SimpleMvvmExamplePageViewModel
{
    public ObservableCollection<Car> Cars { get; set; }

    public ICommand SetStatusCommand { get; private set; }

    public SimpleMvvmExamplePageViewModel()
    {
        // Set simple dummy data for our ObservableCollection of Cars
        Cars = new ObservableCollection<Car>()
        {
            new Car()
            {
                Name = "Audi R8",
                Seen = false
            },

            new Car()
            {
                Name = "BMW M5",
                Seen = false
            },

            new Car()
            {
                Name = "Ferrari 430 Scuderia",
                Seen = false
            },

            new Car()
            {
                Name = "Lamborghini Veneno",
                Seen = false
            },

            new Car()
            {
                Name = "Mercedes-AMG GT R",
                Seen = false
            }
        };

        SetStatusCommand = new Command(SetStatus);
    }

    private void SetStatus()
    {
        Car selectedCar = Cars.Where(c => c.Seen == false)
            .FirstOrDefault();

        if (selectedCar != null)
        {
            // Change the value and update UI automatically
            selectedCar.Seen = true;
        }
    }
}

此代码将帮助我们实现这种行为:当用户单击Button时,我们将从集合中更改该项目的属性值,并且UI将会刷新,将选中复选框值.

This code will help us to achieve this kind of behaviour: When the user clicks on the Button we will change value of the property of the item from collection and UI will be refreshed, checkbox value will be checked.

此演示的最终结果可以在以下gif波纹管中看到.

The final result of this demo could be seen on this gif bellow.

P.S.我可以将其与ListView中的ItemTapped事件结合起来,但是我想使它变得非常简单,所以这个示例就是这样.

P.S. I could combine this with ItemTapped event from ListView but I wanted to make this very simple so this example is like this.

希望这对您有所帮助,并祝您编程愉快!

Hope this was helpful for you, wishing you lots of luck with coding!

这篇关于更新ListView的ObservableCollection中一项的显示的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆