2012-04-20 42 views
9

我似乎無法弄清楚這一點。我在這裏發現了一些類似的問題,但是我無法弄清楚我的方法的正確方向,或者我正在做一些完全錯誤的事情。綁定到單身類可觀察收藏會員

我的應用程序有一個Singleton類記錄器,它保存我的程序中每個類的日誌消息。

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

} 

現在我要綁定登錄到列表框在我的主窗口,但我想不出綁定

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

工具右邊是我的XAML的單例類的命名空間。我相信這比我想象的簡單,但我只是忽略了一些東西。

回答

18

將您的GetInstance()方法設置爲get屬性。 爲了確保您在訪問它之前實例化您的日誌Observable Collection。這樣,如果綁定在你調用你的第一個Add()方法之前被綁定,綁定將不會被覆蓋。

XAML:

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

記錄儀:

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

這樣做的伎倆,非常感謝你! – metacircle 2012-04-20 08:36:23

3

你可以保持的GetInstance是一種方法和使用的ObjectDataProvider:

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

但同樣你必須初始化_Log構造函數或GetInstance。