Static property not updating in UI

て烟熏妆下的殇ゞ 提交于 2019-12-24 08:18:13

问题


I spent the last hour(s) trying to find an answer in google and stackoverflow. I followed different advices & suggestions, but nothing worked so far. My current code looks like this:

public class GlobalManager : ViewModelBase
{
    static object _LockObject_GFS = new object();
    static double _GlobalFontSize;
    public static double GlobalFontSize
    {
        get
        {
            lock (_LockObject_GFS)
            {
                _GlobalFontSize = GetGlobalResource<double>(LambdaHelper.MemberToString(() => GlobalFontSize));
                return _GlobalFontSize;
            }
        }
        set
        {
            lock (_LockObject_GFS)
            {
                if (_GlobalFontSize != value)
                {
                    _GlobalFontSize = value;
                    SetGlobalResource(value, LambdaHelper.MemberToString(() => GlobalFontSize));
                    NotifyStaticPropertyChanged(() => GlobalFontSize);
                }
            }
        }
    }
}

The getter & setter are both called. NotifyStaticPropertyChanged works and my UI does not update. I've added a TextBlock to check if it updates. Apparently it does not.

<TextBlock Text="{Binding Path=(global:GlobalManager.GlobalFontSize), Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>

If I define a property in my VM (current DataContext), and bind it to a TextBlock, it updates correctly with the current value.

Currently the DependencyProperty Value of a Slider is bound to this property in order to update the font size. (IsSnapToTickEnabled="True")

public double GlobalFontSize
{
    get { return GlobalManager.GlobalFontSize; }
    set { GlobalManager.GlobalFontSize = value; NotifyPropertyChanged(() => GlobalFontSize); }
}

How do I get the binding to work correctly with the static property ? The StaticPropertyChanged event is not null.

StaticPropertyChanged?.Invoke(null, new PropertyChangedEventArgs(propertyName));

Edit 1:

public static void NotifyStaticPropertyChanged(string propertyName)
{
    StaticPropertyChanged?.Invoke(null, new PropertyChangedEventArgs(propertyName));
}

public static void NotifyStaticPropertyChanged<T>(Expression<Func<T> > property)
{
    var expr = property.Body as MemberExpression;
    if (expr == null)
        throw new ArgumentException("Lambda does not contain member expression. () => MyClassOrObject.Property");
    NotifyStaticPropertyChanged(expr.Member.Name);
}

回答1:


Make sure that your GetGlobalResource and SetGlobalResource methods work as expected and that your event signature is correct.

You could refer to the below working sample implementation and compare it to yours:

public class GlobalManager
{
    static object _LockObject_GFS = new object();
    static double _GlobalFontSize;
    public static double GlobalFontSize
    {
        get
        {
            lock (_LockObject_GFS)
            {
                return _GlobalFontSize;
            }
        }
        set
        {
            lock (_LockObject_GFS)
            {
                if (_GlobalFontSize != value)
                {
                    _GlobalFontSize = value;
                    NotifyStaticPropertyChanged(()=> GlobalFontSize);
                }
            }
        }
    }

    public static event EventHandler<PropertyChangedEventArgs> StaticPropertyChanged;

    public static void NotifyStaticPropertyChanged(string propertyName)
    {
        StaticPropertyChanged?.Invoke(null, new PropertyChangedEventArgs(propertyName));
    }

    public static void NotifyStaticPropertyChanged<T>(Expression<Func<T>> property)
    {
        var expr = property.Body as MemberExpression;
        if (expr == null)
            throw new ArgumentException("Lambda does not contain member expression. () => MyClassOrObject.Property");
        NotifyStaticPropertyChanged(expr.Member.Name);
    }
}

Edit: It doesn't work if the event is defined in a base class though.

public abstract class MyBaseViewModel
{
    public static event EventHandler<PropertyChangedEventArgs> StaticPropertyChanged;

    public static void NotifyStaticPropertyChanged(string propertyName)
    {
        StaticPropertyChanged?.Invoke(null, new PropertyChangedEventArgs(propertyName));
    }

    public static void NotifyStaticPropertyChanged<T>(Expression<Func<T>> property)
    {
        var expr = property.Body as MemberExpression;
        if (expr == null)
            throw new ArgumentException("Lambda does not contain member expression. () => MyClassOrObject.Property");
        NotifyStaticPropertyChanged(expr.Member.Name);
    }
}

public class GlobalManager : MyBaseViewModel
{
    static object _LockObject_GFS = new object();
    static double _GlobalFontSize = 10.0;
    public static double GlobalFontSize
    {
        get
        {
            lock (_LockObject_GFS)
            {
                return _GlobalFontSize;
            }
        }
        set
        {
            lock (_LockObject_GFS)
            {
                if (_GlobalFontSize != value)
                {
                    _GlobalFontSize = value;
                    NotifyStaticPropertyChanged("GlobalFontSize");
                }
            }
        }
    }
}

The StaticPropertyChangedEvent must be defined in same class where property resides for the binding to get updated:

View is not getting notified when value of static Property Changes



来源:https://stackoverflow.com/questions/42110956/static-property-not-updating-in-ui

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!