如何在WPF全局处理OnPropertyChanged事件并在所有窗体中获取变量值
没问题,我来帮你搞定在所有窗体里监听Connected属性变化并获取其值的需求!
首先,先确保你的App类完整实现了INotifyPropertyChanged接口——从你给的代码看,OnPropertyChanged方法可能没写完,先补全这部分:
using System; using System.ComponentModel; using System.Windows; public partial class App : Application, INotifyPropertyChanged { #region - Connected - /// <summary> /// Gets or sets Connected status /// </summary> private Boolean connected = false; public Boolean Connected { get { return connected; } set { if(connected != value) { connected = value; OnPropertyChanged(nameof(Connected)); // 用nameof代替硬编码字符串,重构更安全 } } } #endregion #region INotifyPropertyChanged Implementation public event PropertyChangedEventHandler PropertyChanged; protected virtual void OnPropertyChanged(string propertyName) { // 空值检查避免空引用异常 PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); } #endregion }
接下来,在每个需要监听的窗体里,我们可以通过App.Current获取自定义的App实例,然后订阅它的PropertyChanged事件,同时别忘了在窗体关闭时取消订阅(防止内存泄漏)。
单个窗体的实现示例
using System; using System.Windows; public partial class MainWindow : Window { private App _currentApp; public MainWindow() { InitializeComponent(); // 获取当前应用实例 _currentApp = App.Current as App; if (_currentApp != null) { // 订阅属性变化事件 _currentApp.PropertyChanged += OnAppPropertyChanged; // 初始化时先获取一次当前的Connected值 UpdateConnectedUI(_currentApp.Connected); } } private void OnAppPropertyChanged(object sender, PropertyChangedEventArgs e) { // 只处理Connected属性的变化 if (e.PropertyName == nameof(App.Connected)) { UpdateConnectedUI(_currentApp.Connected); } } // 根据Connected状态更新UI或处理业务逻辑 private void UpdateConnectedUI(bool isConnected) { if (isConnected) { StatusLabel.Content = "✅ 已连接"; ConnectBtn.IsEnabled = false; DisconnectBtn.IsEnabled = true; } else { StatusLabel.Content = "❌ 未连接"; ConnectBtn.IsEnabled = true; DisconnectBtn.IsEnabled = false; } } // 窗体关闭时取消订阅,避免内存泄漏 protected override void OnClosed(EventArgs e) { base.OnClosed(e); if (_currentApp != null) { _currentApp.PropertyChanged -= OnAppPropertyChanged; } } }
优化方案:用基类减少重复代码
如果你的应用有很多窗体都需要监听这个属性,直接复制粘贴代码太麻烦。可以创建一个基类窗体,把订阅、取消订阅和基础逻辑放在里面,其他窗体继承这个基类即可:
using System; using System.Windows; public class BaseConnectedWindow : Window { protected App _currentApp; protected override void OnInitialized(EventArgs e) { base.OnInitialized(e); _currentApp = App.Current as App; if (_currentApp != null) { _currentApp.PropertyChanged += OnAppPropertyChanged; UpdateConnectedStatus(_currentApp.Connected); } } protected virtual void OnAppPropertyChanged(object sender, PropertyChangedEventArgs e) { if (e.PropertyName == nameof(App.Connected)) { UpdateConnectedStatus(_currentApp.Connected); } } // 让子类重写这个方法,实现各自的UI或业务逻辑 protected virtual void UpdateConnectedStatus(bool isConnected) { } protected override void OnClosed(EventArgs e) { base.OnClosed(e); if (_currentApp != null) { _currentApp.PropertyChanged -= OnAppPropertyChanged; } } }
然后其他窗体只要继承这个基类,重写UpdateConnectedStatus方法就行:
public partial class SettingsWindow : BaseConnectedWindow { public SettingsWindow() { InitializeComponent(); } protected override void UpdateConnectedStatus(bool isConnected) { // 这里写SettingsWindow特有的逻辑 SyncToggle.IsEnabled = isConnected; } }
这样就可以在所有窗体里轻松监听Connected属性的变化,并且随时获取它的当前值啦!
内容的提问来源于stack exchange,提问作者luka
相关产品推荐
相关产品推荐

