2016-10-04 2 views
-1

Mein Ziel ist ein Singletin mit meiner Anwendung freigegebene Daten, Einstellungen, etc. Ich möchte Singleton über meine gesamte Anwendung und möchte es 2-Wege-bindbar sein in WPF mit INotify.Erstellen eines statischen Singleton/Speichern für Einstellungen mit INotify für WPF-Bindung

Ich lese, dass .net 4.5 kann StaticPropertyChanged verwenden, so frage ich mich, ob das unten ist, wie ich es als Dokumentation implementieren würde, scheint spotty dafür.

public static class Global 
{ 
    public static event EventHandler<PropertyChangedEventArgs> StaticPropertyChanged; 
    private static void CallPropChanged(string Prop) 
    { 
     StaticPropertyChanged?.Invoke(Settings, new PropertyChangedEventArgs(Prop)); 
    } 
    private static Store Settings = new Store(); 

    public static int setting1 
    { 
     get { return Settings._setting1; } 
     set { if (value != Settings._setting1) { Settings._setting1 = value; CallPropChanged("setting1"); } } 
    } 
} 

internal sealed class Store 
{ 
    internal int _setting1; 
} 

Bin ich auf dem richtigen Weg für das, was ich erreichen möchte?

Edit: hat einige Modifikationen:

public sealed class Global:INotifyPropertyChanged 
{ 
    public event PropertyChangedEventHandler PropertyChanged; 

    static readonly Global _instance = new Global(); 

    private int _setting1; 
    private int _setting2; 

    private void CallPropChanged(string propertyName = null) 
    { 
     PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); 
    } 

    private bool SetField<T>(ref T field, T value, [CallerMemberName] string propertyName = null) 
    { 
     if (EqualityComparer<T>.Default.Equals(field, value)) return false; 
     field = value; 
     CallPropChanged(propertyName); 
     return true; 
    } 

    private Global() { } 

    public static int setting1 
    { 
     get { return _instance._setting1; } 
     set { _instance.SetField(ref _instance._setting1, value); } 
    } 
    public static int setting2 
    { 
     get { return _instance._setting2; } 
     set { _instance.SetField(ref _instance._setting2, value); } 
    } 

} 
+0

Haben Sie, was Sie versucht, Arbeit? Wenn ja, was ist deine Frage? Wenn nicht, was ist passiert und was _speziell_ benötigen Sie Hilfe? Es scheint mir, dass wenn Sie ein Singleton implementieren (der Code, den Sie gepostet haben, tut das nicht), dann kann das Singleton-Objekt selbst 'INotifyPropertyChanged' wie üblich implementieren. Bitte verbessern Sie die Frage, damit klar ist, womit Sie tatsächlich Probleme haben. Stellen Sie sicher, dass Sie ein gutes [mcve] enthalten, das zuverlässig jedes Problem reproduziert, in das Sie geraten. –

+0

@PeterDuniho Definiert einen Instanzspeicher nicht in einer statischen Weise, um einen Singleton zu erstellen? Oder erstellt es immer noch eine neue Instanz des Geschäfts bei jedem Aufruf? Ich möchte an das Statische binden, und Statisch kann nicht implementieren INotify – Wobbles

+0

_ "Definiert ein Instance-Speicher nicht in einem statischen eine Möglichkeit, ein Singleton zu erstellen?" _ - Nein. Der Begriff "Singleton" hat eine sehr spezifische Bedeutung und gilt nicht für den von Ihnen geposteten Code. Mit einem Singleton haben Sie eine 'public static'-Eigenschaft, die die Instanz _single_ Ihrer Klasse zurückgibt, aber die Klasse selbst und alle ihre Member sind immer noch nicht-statisch. Dann können Sie Schnittstellen (wie 'INPC') implementieren. Sie können _instate_ 'StaticPropertyChanged' verwenden, aber das ist kein Singleton. Es ist nur eine statische Klasse, mit der WPF umgehen kann. Siehe z.B. [diese Antwort] (http://stackoverflow.com/a/9786554) für mehr. –

Antwort

0

Ich bin nicht vertraut mit StaticPropertyChanged, aber ich habe Singleton Viewmodels wie folgt umgesetzt:

public class MyViewModel : ViewModelBase 
{ 
    public static MyViewModel Instance { get; set; } 
    public static ICommand MyCommand { get; set; } 

    public MyViewModel() 
    { 
     Instance = this; 
    } 
} 

und gebundene Tasten, etc in XAML wie diese :

Sie können das Präfix x: Static verwenden, um an das statische Feld zu binden s, und Sie können INotifyPropertyChanged normal verwenden ... Möglicherweise stellen Sie fest, dass diese bestimmte Bindung nicht tatsächlich die Singleton-Instanz der VM erfordert, aber um mit dem Singleton-Modell zu bleiben, können Sie auch an {x: Static vm: MyViewModel binden .Instance.Wherever}

+0

Ich nehme an, Sie müssen auf die Eigenschaften über 'Instance' zugreifen, und was ist der Punkt einer statischen Eigenschaft innerhalb einer Instanz? Muss 'MyCommand' eine Instanz sein? Der einzige Grund, 'MyCommand' static zu machen, ist, wenn es sich um eine Verknüpfung zum Zugriff auf ein' MyViewModel.Instance._MyCommand' Feld handelt. Recht? Oder bin ich gerade verloren lol. – Wobbles

+0

Das obige ist auch keine Singleton-Implementierung. Das Singleton-Muster hat einige spezifische Anforderungen, von denen eine _ es nicht möglich ist, mehr als eine Instanz des Typs zu erstellen. Der Konstruktor ist privat und es gibt ein statisches Feld, das die Instanz _single_ dieses Typs speichert und nur einmal initialisiert wird. Eine bessere Implementierung des Musters würde das Feld im Konstruktor auch nicht initialisieren. In .NET ist die 'Lazy ' Klasse nützlich für Singletons, die teuer zu erstellen sind und nicht immer verwendet werden, ansonsten genügt ein einfacher Feldinitialisierer. –

+0

@PeterDuniho Mein zweites Beispiel hat das, aber du sagst, dass das auch kein Singleton ist. Ich kopiere meinen Code von Singleton-Beispielen, so dass ich nicht sicher bin, was es sonst noch gibt. – Wobbles

Verwandte Themen