更新ListView的ObservableCollection中一项的显示 [英] Update display of one item in a ListView's 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屋!