WPF中静态属性变更后如何通知所有窗口刷新ListView
解决方案
核心问题说明
你的代码无法自动刷新的两个根本原因:
- 静态属性默认不支持常规
INotifyPropertyChanged的实例通知事件- 你每次直接替换
AllTasks的集合实例,绑定了旧实例的控件无法感知到实例替换
方案1(推荐):复用ObservableCollection实例,避免重复赋值
ObservableCollection本身已经实现了集合变更通知,只要不替换实例,直接操作集合元素,所有绑定该集合的控件会自动同步刷新,无需额外实现通知逻辑。
修改App.xaml.cs代码
public partial class App : Application { // 只读属性,保证全局只有一个集合实例 public static ObservableCollection<tasks> AllTasks { get; } = new ObservableCollection<tasks>(); protected override void OnStartup(StartupEventArgs e) { base.OnStartup(e); // 启动时加载初始化数据 AllTasks.Clear(); foreach (var task in Core.db.tasks.ToList()) { AllTasks.Add(task); } } }
修改新增任务逻辑
private void OnAddTaskExecuted(object p) { tasks tsk = new tasks() { taskname = "1", description = "", date = DateTime.Now, empID = 2 }; Core.db.tasks.Add(tsk); Core.db.SaveChanges(); // 直接向现有集合添加元素,无需重新实例化集合 App.AllTasks.Add(tsk); }
绑定写法
所有窗口的ListView的ItemsSource直接按以下方式绑定即可自动同步:
<ListView ItemsSource="{Binding Source={x:Static local:App.AllTasks}}" />
注:local为你的App类所在的命名空间别名
方案2:实现静态属性变更通知(适合必须替换集合实例的场景)
WPF 4.5及以上版本原生支持静态属性变更通知,只需在App类中声明静态通知事件,属性赋值时触发即可。
修改App.xaml.cs代码
using System.ComponentModel; public partial class App : Application { private static ObservableCollection<tasks> _AllTasks; public static ObservableCollection<tasks> AllTasks { get => _AllTasks; set { _AllTasks = value; // 触发静态属性变更通知 StaticPropertyChanged?.Invoke(null, new PropertyChangedEventArgs(nameof(AllTasks))); } } // 声明静态属性变更事件 public static event EventHandler<PropertyChangedEventArgs> StaticPropertyChanged; protected override void OnStartup(StartupEventArgs e) { base.OnStartup(e); AllTasks = new ObservableCollection<tasks>(Core.db.tasks.ToList()); } }
绑定写法
注意此时不能用x:Static方式绑定,需要用路径绑定写法:
<ListView ItemsSource="{Binding Path=(local:App.AllTasks)}" />
补充说明
如果需要任务对象的单个属性(比如taskname、date)变更时UI也同步更新,需要给tasks类实现INotifyPropertyChanged接口,每个属性的set访问器中触发PropertyChanged事件即可。
内容的提问来源于stack exchange,提问作者nsv
相关产品推荐
相关产品推荐

