简体   繁体   English

如何使用 AdvancedCollectionView 源更新 UWP ListView 中的项目

[英]How to update item in UWP ListView with AdvancedCollectionView source

I am using AdvanceCollectionView from Windows Community Toolkit as a source for a XAML ListView, to allow sorting and filtering.我正在使用 Windows 社区工具包中的AdvanceCollectionView作为 XAML ListView 的来源,以允许排序和过滤。 I am having problems with updating the ListView.我在更新 ListView 时遇到问题。

To replicate the issue, I've created a simple Person class.为了重现这个问题,我创建了一个简单的Person class。 In MainPage XAML I have a ListView MyXAMLList and a Button EditButton .MainPage XAML 我有一个ListView MyXAMLList和一个Button EditButton In the MainPage code, I have an ObservableCollection<Person> MyPersonList and AdvancedCollectionView MyPersonACV .MainPage代码中,我有一个ObservableCollection<Person> MyPersonListAdvancedCollectionView MyPersonACV In Page_Loaded event I add a person to the list and use AdvancedCollectionView as a source for the list view:Page_Loaded事件中,我将一个人添加到列表中并使用 AdvancedCollectionView 作为列表视图的源:

Person p = new Person
{
    Name = "John",
    Age = 35
};

MyPersonList.Add(p);
MyPersonACV = new AdvancedCollectionView(MyPersonList, true);
MyXAMLList.ItemsSource = MyPersonACV;    

This works and I can see John in the list.这行得通,我可以在列表中看到 John。

In the EditButton code I try to update the item on the list but this isn't working.EditButton代码中,我尝试更新列表中的项目,但这不起作用。 Both the ObservableCollection and the AdvancedCollectionView are updated, but the XAML list is still displaying the old name "John" instead of "Mary". ObservableCollection 和 AdvancedCollectionView 都已更新,但 XAML 列表仍显示旧名称“John”而不是“Mary”。

MyPersonList[0].Name = "Mary";

Debug.WriteLine(MyPersonList[0].ToString());
Debug.WriteLine(MyPersonACV[0].ToString());
        

I've tried updating the MyXAMLList.SelectedItem instead, but the same result:我尝试更新 MyXAMLList.SelectedItem ,但结果相同:

Person p = (Person)MyXAMLList.SelectedItem;
p.Name = "Mary";

I've also tried adding MyPersonACV.Refresh();我也试过添加MyPersonACV.Refresh(); but doesn't help.但没有帮助。

What am I doing wrong?我究竟做错了什么? How can I update an item in the list?如何更新列表中的项目?

Full code below完整代码如下

Person class:人 class:

class Person
{
    public string Name {get; set;}
    public int Age { get; set; }
    public override string ToString()
    {
        return Name;
    }
}

MainPage XAML:主页 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>

MainPage cs:主页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;
        }
        

    }
}

I noticed you override the ToString() method to display each item of ListView.我注意到您重写了ToString()方法来显示 ListView 的每个项目。 When you update the Name property, even if the value of Name property has updated, since there is no binding relationship between Name property and ListViewItem, and the ToString() method isn't triggered when you update data, the UI isn't updated.更新 Name 属性时,即使 Name 属性的值更新了,由于 Name 属性和 ListViewItem 没有绑定关系,并且更新数据时不会触发 ToString() 方法,所以 UI 不会更新. It'sbetter to customize the appearance of items using DataTemplate , binding the Name property to the element(eg TetxBlock) and implement INotifyPropertyChanged interface.最好使用DataTemplate自定义项目的外观,将 Name 属性绑定到元素(例如 TetxBlock)并实现INotifyPropertyChanged接口。 In this case, when the Name proeprty changes, it will provide change notifications to the binding and the UI will update.在这种情况下,当 Name 属性发生更改时,它将向绑定提供更改通知,并且 UI 将更新。 For exmaple:例如:

.xaml: .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: 。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";
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM