如何使用 AdvancedCollectionView 源更新 UWP ListView 中的项目
Posted
技术标签:
【中文标题】如何使用 AdvancedCollectionView 源更新 UWP ListView 中的项目【英文标题】:How to update item in UWP ListView with AdvancedCollectionView source 【发布时间】:2020-10-22 11:22:21 【问题描述】:我使用来自 Windows Community Toolkit 的 AdvanceCollectionView 作为 XAML ListView 的源,以允许排序和过滤。我在更新 ListView 时遇到问题。
为了重现这个问题,我创建了一个简单的Person
类。在MainPage
XAML 中,我有一个ListView MyXAMLList
和一个Button EditButton
。在MainPage
代码中,我有一个ObservableCollection<Person> MyPersonList
和AdvancedCollectionView MyPersonACV
。在Page_Loaded
事件中,我将一个人添加到列表中,并使用 AdvancedCollectionView 作为列表视图的来源:
Person p = new Person
Name = "John",
Age = 35
;
MyPersonList.Add(p);
MyPersonACV = new AdvancedCollectionView(MyPersonList, true);
MyXAMLList.ItemsSource = MyPersonACV;
这行得通,我可以在列表中看到 John。
在EditButton
代码中,我尝试更新列表中的项目,但这不起作用。 ObservableCollection 和 AdvancedCollectionView 都已更新,但 XAML 列表仍显示旧名称“John”而不是“Mary”。
MyPersonList[0].Name = "Mary";
Debug.WriteLine(MyPersonList[0].ToString());
Debug.WriteLine(MyPersonACV[0].ToString());
我已尝试更新 MyXAMLList.SelectedItem,但结果相同:
Person p = (Person)MyXAMLList.SelectedItem;
p.Name = "Mary";
我也尝试添加MyPersonACV.Refresh();
,但没有帮助。
我做错了什么?如何更新列表中的项目?
完整代码如下
人物类:
class Person
public string Name get; set;
public int Age get; set;
public override string ToString()
return Name;
主页 XAML:
<Page
x:Class="App3.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:App3"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
Background="ThemeResource ApplicationPageBackgroundThemeBrush"
Loaded="Page_Loaded">
<Grid>
<StackPanel Orientation="Vertical">
<ListView Height="Auto" Width="Auto" x:Name="MyXAMLList" SelectionMode="Single" IsItemClickEnabled="True"/>
<StackPanel Orientation="Horizontal">
<Button x:Name="EditButton" Content="Edit" Click="EditButton_Click"/>
</StackPanel>
</StackPanel>
</Grid>
</Page>
主页cs:
using Microsoft.Toolkit.Uwp.UI;
using System.Collections.ObjectModel;
using System.Diagnostics;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
namespace App3
public sealed partial class MainPage : Page
private ObservableCollection<Person> MyPersonList = new ObservableCollection<Person>();
private AdvancedCollectionView MyPersonACV;
public MainPage()
this.InitializeComponent();
private void EditButton_Click(object sender, RoutedEventArgs e)
//Change name
MyPersonList[0].Name = "Mary";
//Person p = (Person)MyXAMLList.SelectedItem;
//p.Name = "Mary";
Debug.WriteLine(MyPersonList[0].ToString());
Debug.WriteLine(MyPersonACV[0].ToString());
//MyPersonACV.Refresh();
private void Page_Loaded(object sender, RoutedEventArgs e)
//create person
Person p = new Person
Name = "John",
Age = 35
;
//add to list
MyPersonList.Add(p);
//set up ListView source
MyPersonACV = new AdvancedCollectionView(MyPersonList, true);
MyXAMLList.ItemsSource = MyPersonACV;
【问题讨论】:
【参考方案1】:我注意到你重写了ToString()
方法来显示ListView 的每一项。更新 Name 属性时,即使 Name 属性的值更新了,由于 Name 属性和 ListViewItem 没有绑定关系,并且更新数据时不会触发 ToString() 方法,所以 UI 不会更新.最好使用 DataTemplate 自定义项目的外观,将 Name 属性绑定到元素(例如 TetxBlock)并实现 INotifyPropertyChanged 接口。在这种情况下,当 Name 属性更改时,它将向绑定提供更改通知,并且 UI 将更新。例如:
.xaml:
<ListView Height="Auto" Width="Auto" x:Name="MyXAMLList" SelectionMode="Single" IsItemClickEnabled="True">
<ListView.ItemTemplate>
<DataTemplate>
<TextBlock Text="Binding Name"></TextBlock>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
.cs:
public class Person : INotifyPropertyChanged
public event PropertyChangedEventHandler PropertyChanged = delegate ;
private string name get; set;
public string Name
get
return name;
set
name = value;
OnPropertyChanged();
public int Age get; set;
public void OnPropertyChanged([CallerMemberName] string propertyName = null)
this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
private void EditButton_Click(object sender, RoutedEventArgs e)
//Change name
MyPersonList[0].Name = "Mary";
【讨论】:
谢谢,确实有效。但是 AdvancedCollectionView 的文档说我不必使用 ObservableCollection 并且可以使用简单的通用列表。我以为 ACV 会解决这个问题? “没有必要使用例如 ObservableCollection 来使用 AdvancedCollectionView。即使在构造函数中提供一个简单的列表时,它也可以按预期工作。” (docs.microsoft.com/en-us/windows/communitytoolkit/helpers/…)以上是关于如何使用 AdvancedCollectionView 源更新 UWP ListView 中的项目的主要内容,如果未能解决你的问题,请参考以下文章
如何在自动布局中使用约束标识符以及如何使用标识符更改约束? [迅速]
如何使用 AngularJS 的 ng-model 创建一个数组以及如何使用 jquery 提交?