2017-02-08 1 views
0

지난 1 시간 동안 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이 작동하고 UI가 업데이트되지 않습니다. 업데이트 여부를 확인하기 위해 TextBlock을 추가했습니다. 분명히 그렇지 않습니다.

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

내 VM (현재의 DataContext)의 속성을 정의하고, TextBlock에 바인딩 경우, 현재의 값을 올바르게 업데이트합니다.

현재 글꼴 크기를 업데이트하기 위해 SliderDependencyPropertyValue이이 속성에 바인딩됩니다. (IsSnapToTickEnabled="True")

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

는 어떻게 정적 속성을 제대로 작동하려면 바인딩을받을 수 있나요? StaticPropertyChanged 이벤트가 null이 아닙니다.

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

편집 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

GetGlobalResourceSetGlobalResource 방법은 예상대로 및 이벤트 서명이 올바른지 작동하는지 확인합니다.

당신은 아래의 작업 샘플 구현을 참조 당신에게 비교할 수 :

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

편집 : 이벤트가 비록 기본 클래스에 정의되어있는 경우 그것은 작동하지 않습니다. 속성은 바인딩 업데이트됩니다 할 수있는 위치

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

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

관련 문제