如何在 C# 中使静态属性可观察?

问题描述 投票:0回答:1

我试图让我的 UI 响应静态属性值的变化。我正在使用 MVVM 工具包。使用 [ObservableProperty] 标记静态属性不起作用,原因很明显,如果我查看生成的代码。有没有办法让静态属性像我使用这个构造一样可观察?

[ObservableProperty]
private static bool observedProperty;

我查看了生成的代码,但我并不清楚如何实现这一点。我发现的所有其他方法都基于非静态属性。

c#
1个回答
0
投票

我相信不可能对静态属性实施normal观察,因为

INotifyPropertyChanged
只有每个实例的成员。

所以,如果您需要使用

INotifyPropertyChanged
接口处理一些共享的静态状态,您将需要在实例级代理这样的状态。

例如

class Test : INotifyPropertyChanged, IDisposable
{
    public event PropertyChangedEventHandler? PropertyChanged;
    public static PropertyChangedEventHandler? StaticPropertyChanged;
    
    private static bool observedProperty;
    public static bool ObservedProperty
    {
        get => observedProperty;
        set
        {
            observedProperty = value;
            StaticPropertyChanged?.Invoke(null, new PropertyChangedEventArgs(nameof(ObservedProperty)));
        }
    }
    
    public bool InstanceObservedProperty => ObservedProperty;

    public Test()
    {
        StaticPropertyChanged+=HandleStaticPropertyChanged;
    }

    private void HandleStaticPropertyChanged(object? sender, PropertyChangedEventArgs e)
    {
        Debug.Assert(sender is null);
        if(e.PropertyName == nameof(ObservedProperty))
        {
            OnPropertyChanged(nameof(InstanceObservedProperty));
        }
    }

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

    public void Dispose()
    {
        StaticPropertyChanged -= HandleStaticPropertyChanged;
    }
}

这里我们进行以下操作

  • 实现了自定义静态事件以通知订阅者有关静态属性的更改
  • 一个类的每个实例都订阅这样一个事件,然后在每次静态变量更改时触发每个实例
    PropertyChanged
    事件。
  • 满足
    InotifyPropertyChanged
    要求有一个实例(非静态)属性
    InstanceObservedProperty
    ,它只是代理相应静态属性的值
  • 重要
    IDisposable
    在不需要实例时取消订阅静态事件。如果不取消订阅,您将发生内存泄漏。
  • 您可能会考虑改进内存泄漏预防并使用
    WeakEvent
    (可能是危险的)甚至终结器来确保您不会保留不再需要的引用。

或者,如果您不需要使用精确的

INotyfyProperyChanged
而只需要观察静态属性,那么您可以只使用静态事件并丢弃其余的样本。

© www.soinside.com 2019 - 2024. All rights reserved.