2012-04-20 3 views
9

Я просто не могу понять это. Я нашел несколько подобных Вопросов здесь, но либо я не могу понять правильное направление для моего подхода, либо я делаю что-то совершенно неправильное.Binding To Singleton Класс Observable Collection Member

Мое приложение имеет регистратор Singleton Class Logger, который сохраняет сообщения журнала из каждого класса в моей программе.

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 в моем MainWindow, но я не могу понять, право Binding

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

инструментов является пространство имен класса одноплодной в моем XAML. Я уверен, что это проще, чем я думаю, но я просто что-то пропускаю.

ответ

18

Сделайте свой способ GetInstance(), чтобы получить недвижимость. И чтобы быть уверенным, создайте экземпляр своей наблюдательной коллекции журнала, прежде чем вы сможете ее получить. Таким образом, привязка не будет переопределена, если она связана, прежде чем вы назовете свой первый метод Add().

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

Это сделал трюк, спасибо вам большое! – metacircle

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}"/> 

Но опять-таки вы должны initialize _Log on конструктор или GetInstance.