2012-04-20 27 views
9

Po prostu nie mogę tego zrozumieć. Znalazłem kilka podobnych pytań tutaj, ale albo nie mogę wymyślić właściwego kierunku dla mojego podejścia lub robię coś zupełnie nie tak.Wiązanie z obserwowalnym członkiem kolekcji Singleton Class

Moja aplikacja ma rejestrator zajęć Singleton, który zapisuje wiadomości dziennika z każdej klasy w moim programie.

public class Logger 
{ 
    private Logger() 
    { 

    } 

    private static volatile Logger instance; 

    public static Logger GetInstance() 
    { 
     // DoubleLock 
     if (instance == null) 
     { 
      lock (m_lock) 
      { 
       if (instance == null) 
       { 
        instance = new Logger(); 
       } 
      } 
     } 
     return instance; 
    } 

    //Helper for Thread Safety 
    private static object m_lock = new object(); 

    private ObservableCollection<string> _Log; 

    public ObservableCollection<string> Log 
    { 
     get { return _Log; } 
    } 

    public void Add(string text) 
    { 
     if (_Log == null) 
      _Log = new ObservableCollection<string>(); 

     Log.Add(DateTime.Now.ToString() + " " + text); 
    } 

    public void Clear() 
    { 
     _Log.Clear(); 
    } 

} 

Teraz chcę wiązać dziennika do pola listy w moim MainWindow, ale nie mogę dowiedzieć się, prawo Binding

<ListBox Name="lstboxLog" Grid.Row="2" Margin="10,0,10,10" ItemsSource="{Binding Source={x:Static tools:Logger.Log}}" Height="100" /> 

narzędzi jest nazw klasy singleton w moim XAML. Jestem pewien, że to jest prostsze niż myślę, ale właśnie coś przeoczam.

Odpowiedz

18

Dokonaj metody GetInstance() dla właściwości get. I na pewno buduj swoją logiczną kolekcję Observable przed uzyskaniem do niej dostępu. W ten sposób wiązanie nie zostanie przesłonięte, jeśli jest związane, zanim wywołasz na nim pierwszą metodę Add().

XAML:

ItemsSource="{Binding Source={x:Static tools:Logger.Instance}, Path=Log}" 

Rejestrator:

public static Logger Instance 
    { 
     get 
     { 
     // DoubleLock 
     if (instance == null) 
     { 
     lock (m_lock) 
     { 
      if (instance == null) 
      { 
      instance = new Logger(); 
      } 
     } 
     } 
     return instance; 
     } 
    } 

    //Helper for Thread Safety 
    private static object m_lock = new object(); 

    private ObservableCollection<string> _Log; 

    public ObservableCollection<string> Log 
    { 
     get 
     { 
     if (_Log == null) 
     { 
      _Log = new ObservableCollection<string>(); 
     } 
     return _Log; 
     } 
    } 

    public void Add(string text) 
    { 
     Log.Add(DateTime.Now.ToString() + " " + text); 
    } 
+1

To wystarczyło, dziękuję bardzo! – metacircle

3

Możesz zachować GetInstance się metodę i używać ObjectDataProvider:

<Window.Resources> 
    <ObjectDataProvider x:Key="data" 
         ObjectType="{x:Type local:Logger}" 
         MethodName="GetInstance" /> 
</Window.Resources> 
<ListBox ItemsSource="{Binding Source={StaticResource data},Path=Log}"/> 

Ale znowu trzeba zainicjuj _Log na konstruktor lub GetInstance.