2012-04-20 21 views
9

Tôi dường như không thể tìm ra điều này. Tôi đã tìm thấy một số câu hỏi tương tự ở đây nhưng tôi không thể tìm ra hướng đi đúng đắn cho cách tiếp cận của tôi hoặc tôi đang làm điều gì đó hoàn toàn sai.Binding To Singleton Class Bộ sưu tập quan sát Thành viên

Ứng dụng của tôi có Trình ghi nhật ký lớp Singleton, lưu các thông điệp tường trình từ mọi lớp trong chương trình của tôi.

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

} 

Bây giờ tôi muốn để ràng buộc Log để ListBox trong MainWindow của tôi, nhưng tôi không thể tìm ra quyền Binding

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

công cụ là không gian tên của lớp singleton trong XAML của tôi. Tôi chắc chắn điều này đơn giản hơn tôi nghĩ, nhưng tôi chỉ nhìn cái gì đó.

Trả lời

18

Làm cho phương thức GetInstance() của bạn thành thuộc tính nhận được. Và để ở bên chắc chắn, hãy khởi tạo nhật ký của bạn Bộ sưu tập có thể quan sát trước khi bạn truy cập nó. Bằng cách đó, ràng buộc sẽ không bị quá tải nếu nó bị ràng buộc trước khi bạn gọi phương thức Add() đầu tiên của bạn trên đó.

XAML:

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

Logger:

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

Đó là mẹo, cảm ơn bạn rất nhiều! – metacircle

3

Bạn có thể giữ getInstance là một phương pháp và sử dụng ObjectDataProvider:

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

Nhưng một lần nữa, bạn phải khởi tạo _Log constructor hoặc GetInstance.

Các vấn đề liên quan