【问题标题】:C# WPF binding to observable object in singleton classC# WPF 绑定到单例类中的可观察对象
【发布时间】:2015-01-05 19:48:08
【问题描述】:

我尝试将单例绑定到我的列表视图。 单例是一个简单的日志类,它将所有新传入的日志消息放在一个可观察的对象中。此对象绑定到我的 xaml 代码。

单例类:

namespace Log
{
public sealed class CLog
{
    private CLog() { }

    private static object m_lock = new object();

    private static CLog _instance;
    public static CLog instance
    {
        get
        {
            if (_instance == null)
            {
                lock (m_lock)
                {
                    if (_instance == null)
                    {
                        _instance = new CLog();
                    }
                }
            }
            return _instance;
        }
    }

    private ObservableCollection<CLogMessage> _logs = new ObservableCollection<CLogMessage>();
    public ObservableCollection<CLogMessage> logs
    {
        get
        {
            if (_logs == null)
            {
                _logs = new ObservableCollection<CLogMessage>();
            }
            return _logs;
        }
    }

    public void AddString(string source, string message)
    {
        CLogMessage log = new CLogMessage();
        log.time = DateTime.Now;
        log.source = source;
        log.message = message;
        System.Windows.Application.Current.Dispatcher.Invoke(
            (Action)delegate()
        {
            logs.Add(log);
        });
    }
}

public sealed class CLogMessage
{
    public DateTime time { get; set; }
    public string source { get; set; }
    public string message { get; set; }
}

}

我在 ListView 中的绑定:

<Grid>
    <ListView ItemsSource="{Binding Source={x:Static local:CLog.instance}, Path=logs}">
        <ListView.View>
            <GridView>
                <GridViewColumn Header="Zeit" Width="140" DisplayMemberBinding="{Binding time}"/>
                <GridViewColumn Header="Quelle" Width="140" DisplayMemberBinding="{Binding source}"/>
                <GridViewColumn Header="Nachricht" Width="Auto" DisplayMemberBinding="{Binding message}"/>
            </GridView>
        </ListView.View>
    </ListView>
</Grid>

问题是我的视图没有更新。我通过来自不同类的简单 CLog.instance.logs.Count() 随机测试了单例类以进行调试。工作得很好,我只是在我的视图中显示项目时遇到问题。 我非常模糊的建议是我必须为绑定对象本身实现通知?

谢谢

【问题讨论】:

  • 两个随机注释,C# 中的属性应该是 PascalCase,从技术上讲,这不是单例,因为您没有私有构造函数。除此之外,我不完全确定您为什么会遇到问题,尽管 x:Static 确实看起来很可疑......您为什么不能通过 VM 上的属性公开该集合?
  • 我使用 x:Static 因为属性“instance”是静态的。
  • 如果我使用 Dispatcher 将项目添加到集合中,我过去曾遇到过 UI 无法更新的问题。如果您删除调度程序代码,它是否有效?
  • @BradleyDotNET 因为作者对CLog 使用了单例模式。
  • 好吧,我还是去睡觉吧。我发现了错误。日志视图作为用户控件绑定到我的面板。所以我只是在我的面板上放了一个新的gridview,也使用了我的日志控件这样的精确绑定,瞧,它起作用了。之后,我在日志用户控件设置中发现了一个非常愚蠢的设置:“height='34'”。所以数据总是显示出来,但盒子太小了。是的,我很惭愧。非常感谢您的帮助。

标签: c# wpf xaml binding singleton


【解决方案1】:

我相信这个问题是由于列表视图从一开始就绑定到一个空项目源引起的。由于我现在没有机器来测试这个,也许您可​​以通过更改 _logs 周围的代码来验证这是否属实:

private ObservableCollection<CLogMessage> _logs = 
    new ObservableCollection<CLogMessage>();
public ObservableCollection<CLogMessage> logs
{
    get { return _logs; }
}

public void AddString(string source, string message)
{
    CLogMessage log = new CLogMessage();
    log.time = DateTime.Now;
    log.source = source;
    log.message = message;
    System.Windows.Application.Current.Dispatcher.Invoke(
        (Action)delegate()
    {
        _logs.Add(log);
    });
}

【讨论】:

  • 嗨,对不起。该解决方案没有奏效。但这不就是物业的任务吗?它检查一个对象是否为空,如果是则创建一个新实例。好吧,无论如何它都不起作用。
猜你喜欢
  • 2012-05-01
  • 2017-11-25
  • 1970-01-01
  • 1970-01-01
  • 2015-03-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-12-29
相关资源
最近更新 更多