源更改时 ListView 不会更新 - 即使我实现了 PropertyChanged

ListView does not update when source is changed - Even though I implemented PropertyChanged

我已经为这个问题苦苦挣扎了几个小时:

我正在 MVVM 模式中构建 UWP 应用程序。

问题: 当我更改 ItemSource 的 属性 时,我无法将我的 ListView 的 ItemSource update/rebind 到 ObservableCollection 的新实例值,即使我已经在 属性.

上实现了 IPropertyChanged

详情: 我正在处理的页面有一个 ListView,它的 ItemSource 绑定到一个可观察的集合:

页数:

<ListView ItemsSource="{Binding Orders}" x:Name="OrderListView"><!--Inner bindings works fine--></ListView>

视图模型:

    public ObservableCollection<Order> Orders {
        get { return _Orders; }
        set { Set(ref _Orders, value); }
    }
    private ObservableCollection<Order> _Orders;
    (...)
    //Property changed implementation from video (06:48): https://mva.microsoft.com/en-US/training-courses/windows-10-data-binding-14579?l=O5mda3EsB_1405632527

    public event PropertyChangedEventHandler PropertyChanged;

    public void RaisePropertyChanged([CallerMemberName] string propertyName = null)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }

    //If property is updated with, raise property changed, else don't
    public bool Set<T>(ref T storage, T value, [CallerMemberName] string propertyName = null)
    {
        if (Equals(storage, value))
            return false;
        storage = value;
        RaisePropertyChanged(propertyName);
        return true;
    }

按下 UI 中的按钮时:

<Button Content="Waiter" Click="Waiter_Click" Background="{Binding Waiter, Converter={StaticResource BoolToColorConverter}, FallbackValue='Yellow', TargetNullValue='Red'}"/>

它会欺骗后面代码中的"Waiter_Click"事件处理程序:

private void Waiter_Click(object sender, RoutedEventArgs e)
    {
        var viewModel = ((Button)sender).DataContext as OrderPageViewModel;
        if (viewModel.Waiter) viewModel.Waiter = false;
        else viewModel.Waiter = true;
    }

实现了 Waiter 属性,因此它在 ViewModel 中引发了 PropertyChangedEvent:

public bool Waiter
    {
        get { return _waiter; }
        set { Set(ref _waiter, value); FilterView(); }
    }
private bool _waiter;

按钮在 UI 中更新 - 这很好用。

设置了_waiter的私有字段后,我也想过滤掉一些不想展示的数据。

我在 FilterView() 中执行此操作;方法。 这是通过创建一个新的 ObservableCollection 并设置 Orders 属性:

来完成的
    public void FilterView()
    {    
        var filteredOrderList = new ObservableCollection<Order>();
        //Sorting is done
        Orders = filteredOrderList;
    }

现在。我认为代码:Orders = filteredOrderList;将触发 Orders 属性 的 "setter",并引发 PropertyChanged 事件,就像它对按钮和所有其他正常工作的 UI 元素所做的那样 - 并告诉 ListView 重新绑定到它。然而,ListView 似乎是 ObservableCollection 的旧实例上的 运行,并且不关心我的 PropertyChanged 事件被触发...

我已经调试了程序,我看到filteredOrderList 包含我想要的数据,并且Orders 已更改。但它就像 ViewList 不关心 PropertyChanged 事件被触发...

我不想在 ObservableCollection 中添加和删除项目,因为过滤变得非常复杂...我只想用一个新的替换 Orders ObservableCollection,并让 ViewList 反映我的更改...

我错过了什么吗?我不能多次调用 PropertyChanged 事件吗? (我调用它一次是为了更新按钮,一次是为了更改 Orders ObservableCollection)。

为什么 ListView 没有重新绑定到新列表? -ListView 不关心 PropertyChanged 事件被触发吗?

我将非常感谢任何能解决这个问题或让我朝着正确方向前进的答案或解决方法。

谢谢,抱歉久了post。

看看这两个:

8个半小时后发现错误:

我不小心定义了两次 DataContext:

<Page.DataContext>
    <vm:OrderPageViewModel/>
</Page.DataContext>

并在 ListView 之前的 XAML 文件中进一步向下:

<Grid.DataContext>
    <vm:OrderPageViewModel/>
</Grid.DataContext>

这导致了我的 OrderPageViewModel 的两个实例。

我的 ViewList 然后绑定到 ViewModel 的旧实例,对 ObservableCollection 的新 ViewModel 实例的任何更改都没有反映任何更改。

如果其他人遇到同样的问题:当更改 ObservableCollection 时 ViewList 不会更新 - 这很恰当,因为您创建了 ObservableCollection 的多个实例。

我还发现 ObservableCollection 仅在添加 og 从中删除对象并使用 .Add()、.Remove() 和 .Clear() 方法清除它时才会更新。如果不在 属性 本身中实现它,就不可能调用 "CollectionChanged" 或 "PropertyChanged",就像我在 Waiter 属性.

上所做的那样

我重新制作了过滤功能以清除集合并向其中添加新元素。它解决了我的问题。 :-)

如果不小心,XAML 中的 3 行真的会把你的一天搞得一团糟。

祝你今天愉快,感谢发布之前答案的人:-)