【发布时间】:2016-07-29 17:58:06
【问题描述】:
我已经为这个问题苦苦挣扎了好几个小时了:
我正在以 MVVM 模式构建 UWP 应用程序。
问题:当我更改 ItemSource 的属性值时,我无法让 ListView 的 ItemSource 更新/重新绑定到 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 属性的“设置器”,并引发 PropertyChanged 事件,就像它对按钮和所有其他正常工作的 UI 元素所做的那样 - 并告诉 ListView 重新绑定到它。但是,ListView 似乎在 ObservableCollection 的旧实例上运行,并且不关心我的 PropertyChanged 事件被触发...
我已经调试了程序,我看到filteredOrderList 包含我想要的数据,并且Orders 发生了变化。但这就像 ViewList 不关心 PropertyChanged 事件被触发...
我不想在 ObservableCollection 中添加和删除项目,因为过滤变得非常复杂...我只想用新的替换 Orders ObservableCollection,并让 ViewList 反映我的更改...
我错过了什么吗?我不能多次调用 PropertyChanged 事件吗? (我调用一次是为了更新按钮,一次是为了更改 Orders ObservableCollection)。
为什么 ListView 没有重新绑定到新列表? -ListView 不关心 PropertyChanged 事件被触发吗?
我将非常感谢任何可以解决此问题或向我发送正确方向的答案或解决方法。
谢谢你,很抱歉发了这么长的帖子。
【问题讨论】:
-
有没有办法手动更新 ViewList?没有从它的 ItemSource 添加或删除项目?
标签: c# xaml listview observablecollection propertychanged