2017-02-08 21 views
0

Я провел последние часы, пытаясь найти ответ в google и stackoverflow. Я пошел по разным советам &, но ничего не получилось. Мой текущий код выглядит следующим образом:Статическое свойство не обновляется в UI

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); 
       } 
      } 
     } 
    } 
} 

Поглотитель & сеттер оба называются. NotifyStaticPropertyChanged работает, и мой пользовательский интерфейс не обновляется. Я добавил TextBlock, чтобы проверить, обновляется ли он. По-видимому, это не так.

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

Если я определяю свойство в моей виртуальной машине (текущий DataContext), и привязать его к TextBlock, он правильно обновляется с текущим значением.

В настоящее время DependencyPropertyValueSlider связан с этим имуществом для того, чтобы уточнить размер шрифта. (IsSnapToTickEnabled="True")

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

Как получить привязки для корректной работы со статическим свойством? Событие StaticPropertyChanged не равно нулю.

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); 
} 
+0

@ MM8 'Случай StaticPropertyChanged не null.' Моя подпись верна. – Blacktempel

+0

Как реализован метод NotifyStaticPropertyChanged? – mm8

+0

@ mm8 Как «нормальная» реализация. См. Мое редактирование. – Blacktempel

ответ

1

Убедитесь, что ваши GetGlobalResource и SetGlobalResource методы работы, как ожидается, и что ваша подпись событие является правильным.

Вы можете обратиться к реализации ниже рабочего образца и сравнить его с вашим:

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: Это не работает, если событие определяется в базовом классе, хотя.

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 должны быть определены в том же классе, где свойство заключается в связывании получить обновление:

View is not getting notified when value of static Property Changes

+0

'Если я определяю свойство в моей VM (текущий DataContext) и привязываю его к TextBlock, он корректно обновляется с текущим значением.' Эти методы Get/Set-GlobalResource работают. Помимо этого, имеет ли значение значение, если у меня есть событие StaticPropertyChanged в базовом классе или в классе со статическим свойством? – Blacktempel

+0

«Разве это имеет значение, если у меня есть событие StaticPropertyChanged в базовом классе или в классе со статическим свойством?» Да. – mm8

+1

Странно, но хорошо ... Я сдержу классы до минимума. Спасибо. – Blacktempel

 Смежные вопросы

  • Нет связанных вопросов^_^