14

私はこれを理解できないようです。ここで同様の質問をいくつか見つけましたが、アプローチの正しい方向性を理解できないか、完全に間違ったことをしています。

私のアプリケーションには、プログラム内のすべてのクラスからのログ メッセージを保存するシングルトン クラス ロガーがあります。

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

}

Log を MainWindow の ListBox にバインドしたいのですが、適切なバインドがわかりません。

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

tools は、XAML のシングルトン クラスの名前空間です。これは思ったより簡単だと思いますが、何かを見落としているだけです。

4

2 に答える 2

30

メソッド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);
    }
于 2012-04-20T08:32:06.430 に答える
4

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 を初期化する必要があります。

于 2012-04-20T08:44:05.960 に答える