Binding To Singleton Class Observable Collection Member

自作多情 提交于 2019-12-06 19:01:08

问题


I just can't seem to figure this out. I found some similar Questions here but either I can't figure out the right direction for my approach or I am doing something completly wrong.

My Application has a Singleton Class Logger, which saves Log messages from every class in my program.

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

}

Now I want to bind Log to ListBox in my MainWindow, but I can't figure out the right Binding

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

tools is the namespace of the singleton class in my XAML. I'm sure this is simpler than I think, but I am just overlooking something.


回答1:


Make your GetInstance() method to a get property. And to be on the sure side instantiate your log Observable Collection before you access it. That way the binding won't be overriden if it is bound before you call your first Add() method on it.

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



回答2:


You can keep GetInstance to be a method and use ObjectDataProvider:

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

But again you have to initialize _Log on constructor or GetInstance.



来源:https://stackoverflow.com/questions/10242292/binding-to-singleton-class-observable-collection-member

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!