2012-04-20 19 views
9

Parece que no puedo resolver esto. Encontré algunas Preguntas similares aquí, pero o no puedo encontrar la dirección correcta para mi enfoque o estoy haciendo algo completamente incorrecto.Encuadernación para Singleton Class Observable Collection Miembro

Mi aplicación tiene un registrador de clase Singleton, que guarda los mensajes de registro de todas las clases de mi programa.

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

} 

Ahora quiero unir Acceder a ListBox en mi MainWindow, pero no se puede averiguar la derecha Encuadernación

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

herramientas es el espacio de nombres de la clase Singleton en mi XAML. Estoy seguro de que esto es más simple de lo que creo, pero simplemente estoy pasando por alto algo.

Respuesta

18

Haga su método GetInstance() para obtener una propiedad. Y para estar seguro de crear una instancia de su registro Colección Observable antes de acceder. De esta forma, la vinculación no se anulará si está vinculada antes de llamar al primer método 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

Eso hizo el truco, ¡muchas gracias! – metacircle

3

Puede mantener GetInstance ser un método y utilizar ObjectDataProvider:

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

Pero de nuevo hay que inicializar _Log on constructor o GetInstance.