我似乎无法弄清楚这一点。我在这里找到了一些类似的问题,但要么我无法找到正确的方向,要么我正在做一些完全错误的事情。
我的应用程序有一个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();
}
}
现在我想在我的MainWindow中将Log绑定到ListBox,但我无法弄清楚正确的绑定
<ListBox Name="lstboxLog" Grid.Row="2" Margin="10,0,10,10" ItemsSource="{Binding Source={x:Static tools:Logger.Log}}" Height="100" />
tools是我的XAML中单例类的命名空间。我确信这比我想象的要简单,但我只是忽略了一些东西。
答案 0 :(得分:23)
将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 :(得分: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}"/>
但是你必须在构造函数或GetInstance上初始化_Log。