2016-07-17 16 views
0

Ich bin neu bei PostSharp (habe gerade meine Lizenz) und ich habe versucht, es in meiner App zu verwenden. Ich habe eine Klasse-Einstellungen einen folgende:NotifyPropertyChanged nicht feuernde Veranstaltung [PostSharp]

[NotifyPropertyChanged] 
public class Consts 
{ 
    public string test2 {get; set;} = "foobar"; 

    public string test 
    { 
     get { return GetValue("test"); } 
     set { UpdateSetting(nameof(test), value.ToString(CultureInfo.InvariantCulture)); } 
    } 

    [Pure] 
    public static string GetValue(string s) => ConfigurationManager.AppSettings[nameof(s)]; 

    [Pure] 
    private static void UpdateSetting(string key, string value) 
    { 
     var cfg = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None); 

     cfg.AppSettings.Settings[key].Value = value; 
     cfg.Save(ConfigurationSaveMode.Modified); 

     ConfigurationManager.RefreshSection("appSettings"); 
    } 
} 

Dann auf meinem Teilnehmerklasse:

var cst = new Consts(); 
Post.Cast<Consts, INotifyPropertyChanged>(cst).PropertyChanged += 
       (o, args) => Debug.Write("PropertyChanged fired"); 
cst.test = "test test"; // Gives no result 
cst.test2 = "test test"; // Event firing correctly 

Das Ereignis wird nicht ausgelöst, wenn ich Methoden in meiner Getter & Setter verwenden, obwohl rein markiert, aber Werke gut, wenn es eine einfache Eigenschaft ist.

Ich verbrachte den letzten Tag damit, Google nach Antworten zu durchsuchen, ohne Glück; Kein Thread löst mein Problem.

Was fehlt mir?

Antwort

1

[NotifyPropertyChanged] aspect erkennt Änderungen an Feldern der Klasse und feuert entsprechende Ereignisse basierend auf erkannten Abhängigkeiten ab (Eigenschaftswert abhängig von diesem spezifischen Feld).

In Ihrem Fall ist dies genau das, was test2 Eigenschaft tut und warum Aspekt auf dieser Eigenschaft funktioniert.

Auf der anderen Seite test Eigenschaft kann nicht automatisch arbeiten. Der Wert der Eigenschaft hängt von ConfigurationManager.AppSettings.Item ab. Das erste Problem ist, dass AppSettings eine statische Eigenschaft ist, d. H. Es ist nicht möglich, Änderungen daran zu erkennen. Wenn angenommen wird, dass es sich nie ändert, dann ist das zweite Problem, dass NameValueCollectionINotifyPropertyChanged nicht implementiert, was bedeutet, dass es keine Möglichkeit gibt zu wissen, dass der Wert tatsächlich geändert wurde.

Sie erhalten keine Warnungen, weil Sie beide Methoden als Pure markiert haben, die nicht im üblichen Sinne des Wortes sind. GetValue verwendet globalen veränderbaren Status. SetValue ändert den globalen änderbaren Zustand.

Da es keine Möglichkeit gibt, an AppSettings zu haken, um Änderungen an der Sammlung zu empfangen, müssen Sie die geänderte Benachrichtigung auslösen, wenn die Eigenschaft festgelegt ist. Dies kann durch Aufruf der Methode NotifyPropertyChangedServices.SignalPropertyChanged erfolgen. Ihr Code würde dann wie folgt aussehen:

[NotifyPropertyChanged] 
public class Consts 
{ 
    public string test2 { get; set; } = "foobar"; 

    public string test 
    { 
     get { return GetValue("test"); } 
     set { UpdateSetting(nameof(test), value.ToString(CultureInfo.InvariantCulture)); } 
    } 

    [SafeForDependencyAnalysis] 
    public string GetValue(string s) => ConfigurationManager.AppSettings[nameof(s)]; 

    private void UpdateSetting(string key, string value) 
    { 
     var cfg = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None); 

     cfg.AppSettings.Settings[key].Value = value; 
     cfg.Save(ConfigurationSaveMode.Modified); 

     ConfigurationManager.RefreshSection("appSettings"); 
     NotifyPropertyChangedServices.SignalPropertyChanged(this, key); 
    } 
} 

Beachten Sie, dass, wenn mehrere Instanz von Consts Klasse vorhanden sind, werden sie teilen Änderungen nicht gibt es keine Möglichkeit, dass die Informationen über ConfigurationManaged passieren.

+0

Ich weiß nicht wer du bist, aber ich werde dich finden und dir eine Medaille geben. –

Verwandte Themen